{"id":90019,"date":"2026-08-04T14:57:23","date_gmt":"2026-08-04T06:57:23","guid":{"rendered":"https:\/\/www.wsisp.com\/helps\/90019.html"},"modified":"2026-08-04T14:57:23","modified_gmt":"2026-08-04T06:57:23","slug":"hermes-agent-gateway%e7%bb%9f%e4%b8%80%e6%8e%a7%e5%88%b6%e9%9d%a2%e6%9e%b6%e6%9e%84%e6%b7%b1%e5%ba%a6%e8%a7%a3%e6%9e%90","status":"publish","type":"post","link":"https:\/\/www.wsisp.com\/helps\/90019.html","title":{"rendered":"Hermes Agent Gateway\u7edf\u4e00\u63a7\u5236\u9762\u67b6\u6784\u6df1\u5ea6\u89e3\u6790"},"content":{"rendered":"<h2>Gateway\u7edf\u4e00\u63a7\u5236\u9762\u67b6\u6784\u6df1\u5ea6\u89e3\u6790<\/h2>\n<p>\u6587\u6863\u5b9a\u4f4d&#xff1a;\u672c\u6587\u6863\u662f Hermes Agent \u81ea\u8fdb\u5316\u667a\u80fd\u4f53\u9ad8\u9636\u5b9e\u6218\u77e5\u8bc6\u4f53\u7cfb\u4e2d\u300c\u4ea7\u54c1\u5b9a\u4f4d\u4e0e\u6838\u5fc3\u67b6\u6784\u300d\u7ae0\u8282\u7684\u7b2c\u4e8c\u4e2a\u62c6\u89e3\u70b9&#xff0c;\u805a\u7126\u4e8e Gateway \u7edf\u4e00\u63a7\u5236\u9762\u7684\u67b6\u6784\u8bbe\u8ba1\u3001\u6838\u5fc3\u673a\u5236\u4e0e\u5de5\u7a0b\u5b9e\u73b0\u3002<\/p>\n<p>\u9002\u7528\u8bfb\u8005&#xff1a;\u67b6\u6784\u8bbe\u8ba1\u4eba\u5458\u3001AI Agent \u5e73\u53f0\u5f00\u53d1\u8005\u3001\u540e\u7aef\u9ad8\u7ea7\u5de5\u7a0b\u5e08\u3001\u6280\u672f\u51b3\u7b56\u8005<\/p>\n<p>\u524d\u7f6e\u4f9d\u8d56&#xff1a;\u5efa\u8bae\u5148\u9605\u8bfb\u300a01_\u4ea7\u54c1\u5b9a\u4f4d\u4e0e\u7cfb\u7edf\u5168\u666f\u300b\u4ee5\u5efa\u7acb\u6574\u4f53\u8ba4\u77e5\u6846\u67b6<\/p>\n<hr \/>\n<p>&#x1f449;\u5199\u535a\u5ba2\u7684\u670b\u53cb\u53ef\u4ee5\u770b\u770b\u8fd9\u4e2a&#xff0c;\u52a9\u529b\u5185\u5bb9\u521b\u4f5c&#xff0c;\u61c2\u6280\u672f\u66f4\u61c2\u589e\u957f&#xff0c;\u5f00\u53d1\u8005\u4e0e\u4f01\u4e1a\u7684\u521b\u4f5c\u589e\u957f\u5f15\u64ce &#xff01;&#x1f448;&#x1f449;\u70b9\u51fb\u8fdb\u5165<\/p>\n<h3>\u76ee\u5f55<\/h3>\n<ul>\n<li>\u7b2c\u4e00\u7ae0 Gateway \u67b6\u6784\u603b\u89c8\n<ul>\n<li>1.1 \u8bbe\u8ba1\u7406\u5ff5<\/li>\n<li>1.2 \u6838\u5fc3\u804c\u8d23\u77e9\u9635<\/li>\n<li>1.3 \u5728\u7cfb\u7edf\u4e2d\u7684\u4e2d\u67a2\u5730\u4f4d<\/li>\n<li>1.4 \u67b6\u6784\u5206\u5c42\u89c6\u56fe<\/li>\n<li>1.5 \u6280\u672f\u9009\u578b\u6982\u89c8<\/li>\n<\/ul>\n<\/li>\n<li>\u7b2c\u4e8c\u7ae0 \u4f1a\u8bdd\u7ba1\u7406\u5668\u6df1\u5ea6\u89e3\u6790\n<ul>\n<li>2.1 \u591a\u8f6e\u5bf9\u8bdd\u4e0a\u4e0b\u6587\u7ef4\u62a4<\/li>\n<li>2.2 \u4f1a\u8bdd ID \u8def\u7531\u673a\u5236<\/li>\n<li>2.3 \u4e0a\u4e0b\u6587\u7a97\u53e3\u538b\u7f29\u7b56\u7565<\/li>\n<li>2.4 \u5e76\u884c\u4f1a\u8bdd\u9694\u79bb\u65b9\u6848<\/li>\n<li>2.5 \u4f1a\u8bdd\u751f\u547d\u5468\u671f\u7ba1\u7406<\/li>\n<\/ul>\n<\/li>\n<li>\u7b2c\u4e09\u7ae0 \u6e20\u9053\u9002\u914d\u5668\u67b6\u6784\n<ul>\n<li>3.1 \u9002\u914d\u5668\u6a21\u5f0f\u8bbe\u8ba1<\/li>\n<li>3.2 \u6d88\u606f\u683c\u5f0f\u5f52\u4e00\u5316\u6d41\u7a0b<\/li>\n<li>3.3 \u591a\u5e73\u53f0\u534f\u8bae\u5dee\u5f02\u5904\u7406<\/li>\n<li>3.4 \u56de\u8c03\u673a\u5236\u4e0e\u5f02\u6b65\u6d88\u606f\u5904\u7406<\/li>\n<li>3.5 \u6e20\u9053\u5065\u5eb7\u68c0\u67e5\u4e0e\u6545\u969c\u8f6c\u79fb<\/li>\n<\/ul>\n<\/li>\n<li>\u7b2c\u56db\u7ae0 \u5de5\u5177\u6ce8\u518c\u8868\u8bbe\u8ba1\n<ul>\n<li>4.1 \u5de5\u5177\u6ce8\u518c\u4e0e\u53d1\u73b0\u673a\u5236<\/li>\n<li>4.2 MCP \u534f\u8bae\u96c6\u6210<\/li>\n<li>4.3 \u5185\u7f6e\u5de5\u5177\u4e0e\u81ea\u5b9a\u4e49\u5de5\u5177\u7edf\u4e00\u7ba1\u7406<\/li>\n<li>4.4 \u6743\u9650\u6821\u9a8c\u4e0e\u8c03\u7528\u5ba1\u8ba1<\/li>\n<li>4.5 \u5de5\u5177\u7248\u672c\u7ba1\u7406\u4e0e\u70ed\u66f4\u65b0<\/li>\n<\/ul>\n<\/li>\n<li>\u7b2c\u4e94\u7ae0 \u6838\u5fc3\u8def\u7531\u5f15\u64ce\n<ul>\n<li>5.1 \u610f\u56fe\u8bc6\u522b\u7b97\u6cd5<\/li>\n<li>5.2 \u4efb\u52a1\u7f16\u6392\u7b56\u7565<\/li>\n<li>5.3 \u8bb0\u5fc6\u8c03\u5ea6\u673a\u5236<\/li>\n<li>5.4 \u5b89\u5168\u6c99\u7bb1\u96c6\u6210<\/li>\n<\/ul>\n<\/li>\n<li>\u7b2c\u516d\u7ae0 Gateway \u4e0e\u5176\u4ed6\u6a21\u5757\u7684\u4ea4\u4e92\n<ul>\n<li>6.1 \u4e0e\u8bb0\u5fc6\u7cfb\u7edf\u7684\u534f\u4f5c<\/li>\n<li>6.2 \u4e0e\u6a21\u578b\u8def\u7531\u5668\u7684\u534f\u4f5c<\/li>\n<li>6.3 \u4e0e\u81ea\u8fdb\u5316\u5f15\u64ce\u7684\u534f\u4f5c<\/li>\n<\/ul>\n<\/li>\n<li>\u7b2c\u4e03\u7ae0 Gateway \u6027\u80fd\u4e0e\u6269\u5c55\u6027\n<ul>\n<li>7.1 \u5e76\u53d1\u5904\u7406\u80fd\u529b<\/li>\n<li>7.2 \u6c34\u5e73\u6269\u5c55\u65b9\u6848<\/li>\n<li>7.3 \u6545\u969c\u6062\u590d\u673a\u5236<\/li>\n<\/ul>\n<\/li>\n<li>\u7b2c\u516b\u7ae0 \u4e0e\u5176\u4ed6 Agent \u6846\u67b6\u7684 Gateway \u5bf9\u6bd4\n<ul>\n<li>8.1 \u67b6\u6784\u54f2\u5b66\u5bf9\u6bd4<\/li>\n<li>8.2 \u6838\u5fc3\u80fd\u529b\u5bf9\u6bd4\u77e9\u9635<\/li>\n<li>8.3 \u573a\u666f\u9002\u7528\u6027\u5206\u6790<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<hr \/>\n<h2>\u7b2c\u4e00\u7ae0 Gateway \u67b6\u6784\u603b\u89c8<\/h2>\n<h3>1.1 \u8bbe\u8ba1\u7406\u5ff5<\/h3>\n<p>Gateway \u7edf\u4e00\u63a7\u5236\u9762\u662f Hermes Agent \u67b6\u6784\u4f53\u7cfb\u4e2d\u7684\u4e2d\u67a2\u795e\u7ecf\u7cfb\u7edf&#xff0c;\u5176\u8bbe\u8ba1\u7406\u5ff5\u6839\u690d\u4e8e\u4ee5\u4e0b\u4e94\u4e2a\u6838\u5fc3\u539f\u5219&#xff1a;<\/p>\n<h4>1.1.1 \u5355\u4e00\u5165\u53e3\u539f\u5219&#xff08;Single Entry Point&#xff09;<\/h4>\n<p>\u6240\u6709\u5916\u90e8\u6e20\u9053\u2014\u2014\u65e0\u8bba\u662f Web \u5ba2\u6237\u7aef\u3001\u79fb\u52a8\u5e94\u7528\u3001\u5373\u65f6\u901a\u8baf\u5e73\u53f0\u8fd8\u662f API \u8c03\u7528\u2014\u2014\u90fd\u5fc5\u987b\u7ecf\u8fc7 Gateway \u8fd9\u552f\u4e00\u7684\u5165\u53e3\u70b9\u3002\u8fd9\u4e00\u8bbe\u8ba1\u5e26\u6765\u4e86\u4e09\u4e2a\u5173\u952e\u6536\u76ca&#xff1a;<\/p>\n<ul>\n<li>\u7edf\u4e00\u5b89\u5168\u8fb9\u754c&#xff1a;\u6240\u6709\u8bf7\u6c42\u7ecf\u8fc7\u540c\u4e00\u5957\u8ba4\u8bc1\u3001\u9274\u6743\u3001\u9650\u6d41\u3001\u5ba1\u8ba1\u7ba1\u7ebf&#xff0c;\u6d88\u9664\u4e86\u591a\u5165\u53e3\u5e26\u6765\u7684\u5b89\u5168\u76f2\u533a<\/li>\n<li>\u534f\u8bae\u5f52\u4e00\u5316&#xff1a;\u4e0d\u540c\u6e20\u9053\u7684\u5f02\u6784\u534f\u8bae\u5728 Gateway \u5c42\u9762\u88ab\u7edf\u4e00\u7ffb\u8bd1\u4e3a\u5185\u90e8\u6807\u51c6\u6d88\u606f\u683c\u5f0f&#xff0c;\u4e0b\u6e38\u6a21\u5757\u65e0\u9700\u611f\u77e5\u6e20\u9053\u5dee\u5f02<\/li>\n<li>\u53ef\u89c2\u6d4b\u6027\u6536\u655b&#xff1a;\u5168\u94fe\u8def\u8ffd\u8e2a\u3001\u6307\u6807\u91c7\u96c6\u3001\u65e5\u5fd7\u805a\u5408\u5728\u540c\u4e00\u5c42\u5b8c\u6210&#xff0c;\u4e3a\u7cfb\u7edf\u63d0\u4f9b\u7aef\u5230\u7aef\u7684\u4e8b\u52a1\u53ef\u89c1\u6027<\/li>\n<\/ul>\n<h4>1.1.2 \u63a7\u5236\u9762\u4e0e\u6570\u636e\u9762\u5206\u79bb&#xff08;Control-Data Plane Separation&#xff09;<\/h4>\n<p>Gateway \u4e25\u683c\u9075\u5faa\u4e91\u539f\u751f\u67b6\u6784\u4e2d\u63a7\u5236\u9762\u4e0e\u6570\u636e\u9762\u5206\u79bb\u7684\u8bbe\u8ba1\u8303\u5f0f&#xff1a;<\/p>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502                     Hermes Agent \u7cfb\u7edf\u5168\u666f                             \u2502<br \/>\n\u2502                                                                     \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u63a7\u5236\u4fe1\u53f7   \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u2502<br \/>\n\u2502  \u2502                 \u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&gt; \u2502                             \u2502    \u2502<br \/>\n\u2502  \u2502   \u63a7\u5236\u9762(Gateway) \u2502            \u2502   \u6570\u636e\u9762 (\u6267\u884c\u5c42)             \u2502    \u2502<br \/>\n\u2502  \u2502                 \u2502 &lt;\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2502                             \u2502    \u2502<br \/>\n\u2502  \u2502  \u00b7 \u4f1a\u8bdd\u7ba1\u7406      \u2502   \u72b6\u6001\u56de\u4f20  \u2502  \u00b7 \u6a21\u578b\u63a8\u7406                  \u2502    \u2502<br \/>\n\u2502  \u2502  \u00b7 \u6e20\u9053\u9002\u914d      \u2502            \u2502  \u00b7 \u5de5\u5177\u6267\u884c                  \u2502    \u2502<br \/>\n\u2502  \u2502  \u00b7 \u5de5\u5177\u8c03\u5ea6      \u2502            \u2502  \u00b7 \u8bb0\u5fc6\u8bfb\u5199                  \u2502    \u2502<br \/>\n\u2502  \u2502  \u00b7 \u610f\u56fe\u8def\u7531      \u2502            \u2502  \u00b7 \u5916\u90e8API\u8c03\u7528               \u2502    \u2502<br \/>\n\u2502  \u2502  \u00b7 \u7b56\u7565\u51b3\u7b56      \u2502            \u2502  \u00b7 \u77e5\u8bc6\u68c0\u7d22                  \u2502    \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518            \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2502<br \/>\n\u2502           \u2502                                                          \u2502<br \/>\n\u2502           \u2502  \u63a7\u5236\u6307\u4ee4                                                \u2502<br \/>\n\u2502           v                                                          \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u2502<br \/>\n\u2502  \u2502                    \u57fa\u7840\u8bbe\u65bd\u5c42                                  \u2502    \u2502<br \/>\n\u2502  \u2502  \u6d88\u606f\u961f\u5217  \u00b7  \u5206\u5e03\u5f0f\u7f13\u5b58  \u00b7  \u5bf9\u8c61\u5b58\u50a8  \u00b7  \u65e5\u5fd7\u4e2d\u5fc3  \u00b7  \u76d1\u63a7     \u2502    \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<p>\u63a7\u5236\u9762\u8d1f\u8d23\u300c\u505a\u4ec0\u4e48\u300d\u548c\u300c\u600e\u4e48\u8c03\u5ea6\u300d\u2014\u2014\u51b3\u5b9a\u8bf7\u6c42\u7684\u8def\u7531\u65b9\u5411\u3001\u7f16\u6392\u7b56\u7565\u3001\u5b89\u5168\u7b56\u7565&#xff1b;\u6570\u636e\u9762\u8d1f\u8d23\u300c\u5b9e\u9645\u6267\u884c\u300d\u2014\u2014\u6a21\u578b\u63a8\u7406\u3001\u5de5\u5177\u8c03\u7528\u3001\u8bb0\u5fc6\u6301\u4e45\u5316\u3002\u8fd9\u79cd\u5206\u79bb\u4f7f\u5f97\u63a7\u5236\u903b\u8f91\u53ef\u4ee5\u72ec\u7acb\u6f14\u8fdb\u3001\u72ec\u7acb\u90e8\u7f72\u3001\u72ec\u7acb\u6269\u5c55&#xff0c;\u540c\u65f6\u4e3a\u6570\u636e\u9762\u7684\u591a\u526f\u672c\u6c34\u5e73\u6269\u5c55\u63d0\u4f9b\u4e86\u524d\u63d0\u6761\u4ef6\u3002<\/p>\n<h4>1.1.3 \u58f0\u660e\u5f0f\u914d\u7f6e\u4f18\u4e8e\u786c\u7f16\u7801&#xff08;Declarative over Imperative&#xff09;<\/h4>\n<p>Gateway \u7684\u6240\u6709\u53ef\u53d8\u884c\u4e3a\u2014\u2014\u6e20\u9053\u6620\u5c04\u3001\u5de5\u5177\u8def\u7531\u89c4\u5219\u3001\u9650\u6d41\u7b56\u7565\u3001\u5b89\u5168\u6c99\u7bb1\u7b56\u7565\u2014\u2014\u5747\u901a\u8fc7\u58f0\u660e\u5f0f\u914d\u7f6e\u5b9a\u4e49&#xff0c;\u800c\u975e\u786c\u7f16\u7801\u5728\u4e1a\u52a1\u903b\u8f91\u4e2d\u3002\u8fd9\u4f7f\u5f97\u8fd0\u7ef4\u4eba\u5458\u53ef\u4ee5\u5728\u4e0d\u4fee\u6539\u4ee3\u7801\u7684\u60c5\u51b5\u4e0b\u8c03\u6574\u7cfb\u7edf\u884c\u4e3a&#xff1a;<\/p>\n<p><span class=\"token comment\"># gateway-config.yaml \u2014 Gateway \u58f0\u660e\u5f0f\u914d\u7f6e\u793a\u4f8b<\/span><br \/>\n<span class=\"token key atrule\">gateway<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token key atrule\">server<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">port<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">8080<\/span><br \/>\n    <span class=\"token key atrule\">worker_threads<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">16<\/span><br \/>\n    <span class=\"token key atrule\">max_connections<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">10000<\/span><br \/>\n    <span class=\"token key atrule\">request_timeout<\/span><span class=\"token punctuation\">:<\/span> 120s<br \/>\n    <span class=\"token key atrule\">grpc<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">enabled<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><br \/>\n      <span class=\"token key atrule\">port<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">9090<\/span><br \/>\n      <span class=\"token key atrule\">max_recv_msg_size<\/span><span class=\"token punctuation\">:<\/span> 16MB<\/p>\n<p>  <span class=\"token key atrule\">session<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">default_ttl<\/span><span class=\"token punctuation\">:<\/span> 3600s<br \/>\n    <span class=\"token key atrule\">max_concurrent_per_user<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">5<\/span><br \/>\n    <span class=\"token key atrule\">context_window<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">max_tokens<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">32768<\/span><br \/>\n      <span class=\"token key atrule\">compression_threshold<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">0.75<\/span><br \/>\n      <span class=\"token key atrule\">compression_strategy<\/span><span class=\"token punctuation\">:<\/span> sliding_window_summary<br \/>\n    <span class=\"token key atrule\">storage<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> redis_cluster<br \/>\n      <span class=\"token key atrule\">endpoints<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> redis<span class=\"token punctuation\">&#8211;<\/span>0.internal<span class=\"token punctuation\">:<\/span><span class=\"token number\">6379<\/span><br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> redis<span class=\"token punctuation\">&#8211;<\/span>1.internal<span class=\"token punctuation\">:<\/span><span class=\"token number\">6379<\/span><br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> redis<span class=\"token punctuation\">&#8211;<\/span>2.internal<span class=\"token punctuation\">:<\/span><span class=\"token number\">6379<\/span><br \/>\n      <span class=\"token key atrule\">key_prefix<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;hermes:session:&#034;<\/span><\/p>\n<p>  <span class=\"token key atrule\">channels<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> web<br \/>\n      <span class=\"token key atrule\">adapter<\/span><span class=\"token punctuation\">:<\/span> WebSocketAdapter<br \/>\n      <span class=\"token key atrule\">enabled<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><br \/>\n      <span class=\"token key atrule\">rate_limit<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token key atrule\">requests_per_minute<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">120<\/span><br \/>\n        <span class=\"token key atrule\">burst<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">30<\/span><br \/>\n    <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> feishu<br \/>\n      <span class=\"token key atrule\">adapter<\/span><span class=\"token punctuation\">:<\/span> FeishuAdapter<br \/>\n      <span class=\"token key atrule\">enabled<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><br \/>\n      <span class=\"token key atrule\">rate_limit<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token key atrule\">requests_per_minute<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">60<\/span><br \/>\n      <span class=\"token key atrule\">callback<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token key atrule\">url<\/span><span class=\"token punctuation\">:<\/span> https<span class=\"token punctuation\">:<\/span>\/\/gateway.internal\/feishu\/callback<br \/>\n        <span class=\"token key atrule\">verify_token<\/span><span class=\"token punctuation\">:<\/span> $<span class=\"token punctuation\">{<\/span>FEISHU_VERIFY_TOKEN<span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> dingtalk<br \/>\n      <span class=\"token key atrule\">adapter<\/span><span class=\"token punctuation\">:<\/span> DingTalkAdapter<br \/>\n      <span class=\"token key atrule\">enabled<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><br \/>\n      <span class=\"token key atrule\">rate_limit<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token key atrule\">requests_per_minute<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">60<\/span><br \/>\n    <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> wechat_work<br \/>\n      <span class=\"token key atrule\">adapter<\/span><span class=\"token punctuation\">:<\/span> WeComAdapter<br \/>\n      <span class=\"token key atrule\">enabled<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><br \/>\n    <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> slack<br \/>\n      <span class=\"token key atrule\">adapter<\/span><span class=\"token punctuation\">:<\/span> SlackAdapter<br \/>\n      <span class=\"token key atrule\">enabled<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">false<\/span><br \/>\n    <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> telegram<br \/>\n      <span class=\"token key atrule\">adapter<\/span><span class=\"token punctuation\">:<\/span> TelegramAdapter<br \/>\n      <span class=\"token key atrule\">enabled<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">false<\/span><\/p>\n<p>  <span class=\"token key atrule\">routing<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">intent_model<\/span><span class=\"token punctuation\">:<\/span> hermes<span class=\"token punctuation\">&#8211;<\/span>intent<span class=\"token punctuation\">&#8211;<\/span>v2<br \/>\n    <span class=\"token key atrule\">fallback_strategy<\/span><span class=\"token punctuation\">:<\/span> llm_based<br \/>\n    <span class=\"token key atrule\">max_orchestration_depth<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">8<\/span><br \/>\n    <span class=\"token key atrule\">parallel_task_limit<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">4<\/span><br \/>\n    <span class=\"token key atrule\">timeout_per_task<\/span><span class=\"token punctuation\">:<\/span> 30s<\/p>\n<p>  <span class=\"token key atrule\">tools<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">registry<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> dynamic<br \/>\n      <span class=\"token key atrule\">refresh_interval<\/span><span class=\"token punctuation\">:<\/span> 30s<br \/>\n    <span class=\"token key atrule\">sandbox<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">enabled<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><br \/>\n      <span class=\"token key atrule\">engine<\/span><span class=\"token punctuation\">:<\/span> firecracker<br \/>\n      <span class=\"token key atrule\">memory_limit<\/span><span class=\"token punctuation\">:<\/span> 512MB<br \/>\n      <span class=\"token key atrule\">cpu_limit<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1.0<\/span><br \/>\n      <span class=\"token key atrule\">network<\/span><span class=\"token punctuation\">:<\/span> restricted<br \/>\n      <span class=\"token key atrule\">allowed_domains<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> api.internal<br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token string\">&#034;*.hermes.ai&#034;<\/span><br \/>\n    <span class=\"token key atrule\">audit<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">enabled<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><br \/>\n      <span class=\"token key atrule\">log_retention<\/span><span class=\"token punctuation\">:<\/span> 90d<br \/>\n      <span class=\"token key atrule\">sensitive_params_mask<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><\/p>\n<p>  <span class=\"token key atrule\">observability<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">tracing<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">enabled<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><br \/>\n      <span class=\"token key atrule\">exporter<\/span><span class=\"token punctuation\">:<\/span> otlp<br \/>\n      <span class=\"token key atrule\">endpoint<\/span><span class=\"token punctuation\">:<\/span> jaeger<span class=\"token punctuation\">&#8211;<\/span>collector.observability<span class=\"token punctuation\">:<\/span><span class=\"token number\">4317<\/span><br \/>\n      <span class=\"token key atrule\">sampling_rate<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">0.1<\/span><br \/>\n    <span class=\"token key atrule\">metrics<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">enabled<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><br \/>\n      <span class=\"token key atrule\">exporter<\/span><span class=\"token punctuation\">:<\/span> prometheus<br \/>\n      <span class=\"token key atrule\">port<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">9091<\/span><br \/>\n    <span class=\"token key atrule\">logging<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">level<\/span><span class=\"token punctuation\">:<\/span> info<br \/>\n      <span class=\"token key atrule\">format<\/span><span class=\"token punctuation\">:<\/span> json<br \/>\n      <span class=\"token key atrule\">output<\/span><span class=\"token punctuation\">:<\/span> file<br \/>\n      <span class=\"token key atrule\">path<\/span><span class=\"token punctuation\">:<\/span> \/var\/log\/hermes\/gateway.log<br \/>\n      <span class=\"token key atrule\">rotation<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token key atrule\">max_size<\/span><span class=\"token punctuation\">:<\/span> 100MB<br \/>\n        <span class=\"token key atrule\">max_files<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">10<\/span><br \/>\n        <span class=\"token key atrule\">max_age<\/span><span class=\"token punctuation\">:<\/span> 30d<\/p>\n<h4>1.1.4 \u6e10\u8fdb\u5f0f\u9000\u5316\u539f\u5219&#xff08;Graceful Degradation&#xff09;<\/h4>\n<p>Gateway \u88ab\u8bbe\u8ba1\u4e3a\u5728\u4efb\u4f55\u5355\u70b9\u6545\u969c\u4e0b\u90fd\u80fd\u4fdd\u6301\u6838\u5fc3\u529f\u80fd\u7684\u53ef\u7528\u6027\u3002\u5f53\u8bb0\u5fc6\u7cfb\u7edf\u4e0d\u53ef\u7528\u65f6&#xff0c;Gateway \u9000\u5316\u4e3a\u65e0\u8bb0\u5fc6\u6a21\u5f0f\u7ee7\u7eed\u670d\u52a1&#xff1b;\u5f53\u67d0\u4e2a\u6e20\u9053\u9002\u914d\u5668\u6545\u969c\u65f6&#xff0c;\u5176\u4ed6\u6e20\u9053\u4e0d\u53d7\u5f71\u54cd&#xff1b;\u5f53\u6a21\u578b\u8def\u7531\u5668\u8d85\u65f6\u65f6&#xff0c;Gateway \u4f7f\u7528\u672c\u5730\u7f13\u5b58\u7684\u6700\u4f18\u6a21\u578b\u914d\u7f6e\u6267\u884c\u964d\u7ea7\u63a8\u7406\u3002\u8fd9\u4e00\u539f\u5219\u786e\u4fdd\u4e86\u7cfb\u7edf\u5728\u6076\u52a3\u6761\u4ef6\u4e0b\u7684\u97e7\u6027\u3002<\/p>\n<h4>1.1.5 \u53ef\u63d2\u62d4\u67b6\u6784\u539f\u5219&#xff08;Pluggable Architecture&#xff09;<\/h4>\n<p>Gateway \u7684\u6bcf\u4e00\u4e2a\u6838\u5fc3\u7ec4\u4ef6\u2014\u2014\u6e20\u9053\u9002\u914d\u5668\u3001\u5de5\u5177\u6267\u884c\u5668\u3001\u610f\u56fe\u8bc6\u522b\u5668\u3001\u8bb0\u5fc6\u540e\u7aef\u2014\u2014\u90fd\u901a\u8fc7\u6807\u51c6\u63a5\u53e3\u5b9a\u4e49&#xff0c;\u5b9e\u73b0\u53ef\u63d2\u62d4\u66ff\u6362\u3002\u8fd9\u610f\u5473\u7740\u7528\u6237\u53ef\u4ee5\u7528\u81ea\u5b9a\u4e49\u5b9e\u73b0\u66ff\u6362\u4efb\u4f55\u4e00\u4e2a\u7ec4\u4ef6&#xff0c;\u800c\u65e0\u9700\u4fee\u6539 Gateway \u6838\u5fc3\u4ee3\u7801&#xff1a;<\/p>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502                       Gateway \u53ef\u63d2\u62d4\u67b6\u6784                                  \u2502<br \/>\n\u2502                                                                          \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502<br \/>\n\u2502  \u2502 Channel      \u2502   \u2502 Tool         \u2502   \u2502 Intent       \u2502   \u2502 Memory   \u2502 \u2502<br \/>\n\u2502  \u2502 Adapter SPI  \u2502   \u2502 Executor SPI \u2502   \u2502 Detector SPI \u2502   \u2502 Store SPI\u2502 \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518   \u2514\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2518 \u2502<br \/>\n\u2502         \u2502                  \u2502                  \u2502                \u2502       \u2502<br \/>\n\u2502    \u250c\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2510        \u250c\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2510        \u250c\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2510      \u250c\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2510  \u2502<br \/>\n\u2502    \u2502 \u5185\u7f6e\u5b9e\u73b0 \u2502        \u2502 \u5185\u7f6e\u5b9e\u73b0 \u2502        \u2502 \u5185\u7f6e\u5b9e\u73b0 \u2502      \u2502 \u5185\u7f6e\u5b9e\u73b0 \u2502  \u2502<br \/>\n\u2502    \u2502 Web     \u2502        \u2502 Code    \u2502        \u2502 Rule     \u2502      \u2502 Redis   \u2502  \u2502<br \/>\n\u2502    \u2502 Feishu  \u2502        \u2502 Search  \u2502        \u2502 ML Model \u2502      \u2502 Postgres\u2502  \u2502<br \/>\n\u2502    \u2502 Slack   \u2502        \u2502 HTTP    \u2502        \u2502 LLM Based\u2502      \u2502 Vector  \u2502  \u2502<br \/>\n\u2502    \u2502 &#8230;     \u2502        \u2502 MCP     \u2502        \u2502 Hybrid   \u2502      \u2502 Hybrid  \u2502  \u2502<br \/>\n\u2502    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518        \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518        \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518      \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2502<br \/>\n\u2502    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510        \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510        \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510      \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u2502<br \/>\n\u2502    \u2502 \u7528\u6237\u6269\u5c55 \u2502        \u2502 \u7528\u6237\u6269\u5c55 \u2502        \u2502 \u7528\u6237\u6269\u5c55 \u2502      \u2502 \u7528\u6237\u6269\u5c55 \u2502  \u2502<br \/>\n\u2502    \u2502 Custom  \u2502        \u2502 Custom  \u2502        \u2502 Custom   \u2502      \u2502 Custom  \u2502  \u2502<br \/>\n\u2502    \u2502 Adapter \u2502        \u2502 Tool    \u2502        \u2502 Detector \u2502      \u2502 Store   \u2502  \u2502<br \/>\n\u2502    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518        \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518        \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518      \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<h3>1.2 \u6838\u5fc3\u804c\u8d23\u77e9\u9635<\/h3>\n<p>Gateway \u627f\u62c5\u7740\u56db\u5927\u6838\u5fc3\u804c\u8d23&#xff0c;\u6bcf\u4e00\u9879\u804c\u8d23\u90fd\u5bf9\u5e94\u4e00\u7ec4\u5177\u4f53\u7684\u5b50\u529f\u80fd\u548c\u5de5\u7a0b\u8981\u6c42&#xff1a;<\/p>\n<table>\n<tr>\u804c\u8d23\u57df\u5b50\u529f\u80fd\u5de5\u7a0b\u8981\u6c42\u4f18\u5148\u7ea7<\/tr>\n<tbody>\n<tr>\n<td>\u4f1a\u8bdd\u7ba1\u7406<\/td>\n<td>\u4e0a\u4e0b\u6587\u7ef4\u62a4<\/td>\n<td>\u4f4e\u5ef6\u8fdf\u8bfb\u5199&#xff08;&lt;5ms P99&#xff09;&#xff0c;\u652f\u6301\u591a\u8f6e\u5bf9\u8bdd\u7684\u589e\u91cf\u66f4\u65b0<\/td>\n<td>P0<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>\u4f1a\u8bdd\u8def\u7531<\/td>\n<td>\u57fa\u4e8e\u4f1a\u8bddID\u7684\u7cbe\u786e\u8def\u7531&#xff0c;\u652f\u6301\u8de8\u8282\u70b9\u4f1a\u8bdd\u4eb2\u548c\u6027<\/td>\n<td>P0<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>\u4e0a\u4e0b\u6587\u538b\u7f29<\/td>\n<td>\u5728Token\u9884\u7b97\u5185\u4fdd\u7559\u6700\u5927\u4fe1\u606f\u5bc6\u5ea6<\/td>\n<td>P1<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>\u5e76\u884c\u9694\u79bb<\/td>\n<td>\u540c\u4e00\u7528\u6237\u7684\u591a\u4e2a\u4f1a\u8bdd\u4e92\u4e0d\u5e72\u6270<\/td>\n<td>P0<\/td>\n<\/tr>\n<tr>\n<td>\u6e20\u9053\u9002\u914d<\/td>\n<td>\u534f\u8bae\u5f52\u4e00\u5316<\/td>\n<td>12&#043;\u5e73\u53f0\u6d88\u606f\u683c\u5f0f\u7edf\u4e00\u7ffb\u8bd1<\/td>\n<td>P0<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>\u56de\u8c03\u5904\u7406<\/td>\n<td>\u5f02\u6b65\u6d88\u606f\u63a5\u6536\u4e0e\u5904\u7406&#xff0c;\u4fdd\u8bc1\u81f3\u5c11\u4e00\u6b21\u6295\u9012<\/td>\n<td>P0<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>\u5065\u5eb7\u68c0\u67e5<\/td>\n<td>\u6e20\u9053\u53ef\u7528\u6027\u76d1\u6d4b\u4e0e\u81ea\u52a8\u6545\u969c\u8f6c\u79fb<\/td>\n<td>P1<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>\u9650\u6d41\u7194\u65ad<\/td>\n<td>\u6309\u6e20\u9053\u7c92\u5ea6\u7684\u6d41\u91cf\u63a7\u5236\u4e0e\u7194\u65ad\u4fdd\u62a4<\/td>\n<td>P1<\/td>\n<\/tr>\n<tr>\n<td>\u5de5\u5177\u8c03\u5ea6<\/td>\n<td>\u5de5\u5177\u6ce8\u518c<\/td>\n<td>\u52a8\u6001\u6ce8\u518c\u4e0e\u53d1\u73b0&#xff0c;\u652f\u6301\u70ed\u66f4\u65b0<\/td>\n<td>P0<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>\u6743\u9650\u6821\u9a8c<\/td>\n<td>\u57fa\u4e8eRBAC\u7684\u5de5\u5177\u8c03\u7528\u6743\u9650\u63a7\u5236<\/td>\n<td>P0<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>\u6c99\u7bb1\u9694\u79bb<\/td>\n<td>\u4ee3\u7801\u6267\u884c\u7c7b\u5de5\u5177\u7684\u6c99\u7bb1\u9694\u79bb<\/td>\n<td>P0<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>\u8c03\u7528\u5ba1\u8ba1<\/td>\n<td>\u5168\u91cf\u8c03\u7528\u65e5\u5fd7\u8bb0\u5f55\u4e0e\u5ba1\u8ba1\u8ffd\u8e2a<\/td>\n<td>P1<\/td>\n<\/tr>\n<tr>\n<td>\u8def\u7531\u5f15\u64ce<\/td>\n<td>\u610f\u56fe\u8bc6\u522b<\/td>\n<td>\u57fa\u4e8e\u89c4\u5219&#043;ML&#043;LLM\u7684\u4e09\u7ea7\u610f\u56fe\u8bc6\u522b<\/td>\n<td>P0<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>\u4efb\u52a1\u7f16\u6392<\/td>\n<td>\u652f\u6301\u4e32\u884c\u3001\u5e76\u884c\u3001\u6761\u4ef6\u5206\u652f\u7684\u4efb\u52a1\u7f16\u6392<\/td>\n<td>P0<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>\u8bb0\u5fc6\u8c03\u5ea6<\/td>\n<td>\u6839\u636e\u610f\u56fe\u51b3\u5b9a\u8bb0\u5fc6\u7684\u8bfb\u5199\u7b56\u7565<\/td>\n<td>P1<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>\u964d\u7ea7\u7b56\u7565<\/td>\n<td>\u6a21\u578b\u4e0d\u53ef\u7528\u65f6\u7684\u81ea\u52a8\u964d\u7ea7<\/td>\n<td>P1<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>1.3 \u5728\u7cfb\u7edf\u4e2d\u7684\u4e2d\u67a2\u5730\u4f4d<\/h3>\n<p>Gateway \u5728 Hermes Agent \u7cfb\u7edf\u4e2d\u7684\u4f4d\u7f6e\u53ef\u4ee5\u7528\u300c\u516d\u8fb9\u5f62\u4e2d\u67a2\u300d\u6765\u5f62\u5bb9\u2014\u2014\u5b83\u5411\u4e0a\u5bf9\u63a5\u6240\u6709\u5916\u90e8\u6e20\u9053&#xff0c;\u5411\u4e0b\u8c03\u5ea6\u6240\u6709\u5185\u90e8\u80fd\u529b\u6a21\u5757&#xff0c;\u6a2a\u5411\u8d2f\u7a7f\u8bb0\u5fc6\u7cfb\u7edf\u4e0e\u6a21\u578b\u8def\u7531\u5668&#xff0c;\u540c\u65f6\u63a5\u53d7\u81ea\u8fdb\u5316\u5f15\u64ce\u7684\u7b56\u7565\u6307\u5bfc&#xff1a;<\/p>\n<p>                           \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n                           \u2502    \u81ea\u8fdb\u5316\u5f15\u64ce         \u2502<br \/>\n                           \u2502  (Self-Evolution)    \u2502<br \/>\n                           \u2502  \u00b7 \u7b56\u7565\u4f18\u5316          \u2502<br \/>\n                           \u2502  \u00b7 \u53c2\u6570\u8c03\u4f18          \u2502<br \/>\n                           \u2502  \u00b7 \u80fd\u529b\u8bc4\u4f30          \u2502<br \/>\n                           \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n                                     \u2502 \u7b56\u7565\u4e0b\u53d1<br \/>\n                                     v<br \/>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u8bf7\u6c42    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u8c03\u7528    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502           \u2502 \u2550\u2550\u2550\u2550\u2550\u2550\u2550&gt; \u2502                                 \u2502 \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550&gt; \u2502               \u2502<br \/>\n\u2502  Web UI   \u2502          \u2502                                 \u2502           \u2502  \u6a21\u578b\u8def\u7531\u5668     \u2502<br \/>\n\u2502           \u2502 &lt;\u2550\u2550\u2550\u2550\u2550\u2550\u2550 \u2502      G A T E W A Y              \u2502 &lt;\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 \u2502  (Model       \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524   \u54cd\u5e94    \u2502                                 \u2502   \u7ed3\u679c     \u2502   Router)     \u2502<br \/>\n\u2502           \u2502          \u2502     \u7edf \u4e00 \u63a7 \u5236 \u9762                \u2502           \u2502               \u2502<br \/>\n\u2502  \u98de\u4e66\/\u9489\u9489  \u2502 \u2550\u2550\u2550\u2550\u2550\u2550\u2550&gt; \u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502           \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502           \u2502          \u2502  \u2502 \u4f1a\u8bdd\u7ba1\u7406\u5668  \u2502 \u2502 \u6e20\u9053\u9002\u914d\u5668\u96c6\u7fa4 \u2502 \u2502           \u2502               \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524          \u2502  \u2502 Session   \u2502 \u2502 Adapters     \u2502 \u2502           \u2502  \u8bb0\u5fc6\u7cfb\u7edf      \u2502<br \/>\n\u2502           \u2502          \u2502  \u2502 Manager   \u2502 \u2502              \u2502 \u2502           \u2502  (Memory      \u2502<br \/>\n\u2502  Slack\/   \u2502 \u2550\u2550\u2550\u2550\u2550\u2550\u2550&gt; \u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502           \u2502   System)     \u2502<br \/>\n\u2502  Telegram \u2502          \u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502           \u2502               \u2502<br \/>\n\u2502           \u2502          \u2502  \u2502 \u5de5\u5177\u6ce8\u518c\u8868  \u2502 \u2502 \u6838\u5fc3\u8def\u7531\u5f15\u64ce  \u2502 \u2502 \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550&gt; \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524          \u2502  \u2502 Tool      \u2502 \u2502 Routing      \u2502 \u2502           \u2502               \u2502<br \/>\n\u2502           \u2502          \u2502  \u2502 Registry  \u2502 \u2502 Engine       \u2502 \u2502           \u2502  \u5de5\u5177\u6267\u884c\u5c42     \u2502<br \/>\n\u2502  API\/SDK  \u2502 \u2550\u2550\u2550\u2550\u2550\u2550\u2550&gt; \u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502           \u2502  (Tool        \u2502<br \/>\n\u2502           \u2502          \u2502                                 \u2502           \u2502   Executors)  \u2502<br \/>\n\u2502           \u2502          \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518           \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n\u2502           \u2502                         \u2502<br \/>\n\u2502           \u2502                    \u57fa\u7840\u8bbe\u65bd\u5c42<br \/>\n\u2502           \u2502          \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502           \u2502          \u2502 Redis \u00b7 Kafka \u00b7 S3 \u00b7 ES    \u2502<br \/>\n\u2502           \u2502          \u2502 Jaeger \u00b7 Prometheus \u00b7 ELK  \u2502<br \/>\n\u2502           \u2502          \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<p>\u4ece\u6570\u636e\u6d41\u7684\u89d2\u5ea6\u770b&#xff0c;Gateway \u662f\u6240\u6709\u8bf7\u6c42\u7684\u5fc5\u7ecf\u4e4b\u8def\u3002\u4e00\u4e2a\u5178\u578b\u7684\u8bf7\u6c42\u751f\u547d\u5468\u671f\u5982\u4e0b&#xff1a;<\/p>\n<p>\u7528\u6237\u6d88\u606f \u2192 \u6e20\u9053\u9002\u914d\u5668(\u534f\u8bae\u5f52\u4e00\u5316) \u2192 \u4f1a\u8bdd\u7ba1\u7406\u5668(\u4e0a\u4e0b\u6587\u52a0\u8f7d)<br \/>\n    \u2192 \u6838\u5fc3\u8def\u7531\u5f15\u64ce(\u610f\u56fe\u8bc6\u522b&#043;\u4efb\u52a1\u7f16\u6392)<br \/>\n        \u2192 [\u5e76\u884c] \u6a21\u578b\u8def\u7531\u5668(LLM\u63a8\u7406) &#043; \u8bb0\u5fc6\u7cfb\u7edf(\u8bb0\u5fc6\u68c0\u7d22)<br \/>\n    \u2192 \u5de5\u5177\u6ce8\u518c\u8868(\u5de5\u5177\u8c03\u7528) \u2192 \u7ed3\u679c\u805a\u5408<br \/>\n    \u2192 \u4f1a\u8bdd\u7ba1\u7406\u5668(\u4e0a\u4e0b\u6587\u66f4\u65b0) \u2192 \u6e20\u9053\u9002\u914d\u5668(\u683c\u5f0f\u8f6c\u6362) \u2192 \u7528\u6237\u54cd\u5e94<\/p>\n<h3>1.4 \u67b6\u6784\u5206\u5c42\u89c6\u56fe<\/h3>\n<p>Gateway \u5185\u90e8\u91c7\u7528\u6e05\u6670\u7684\u516d\u5c42\u67b6\u6784&#xff0c;\u6bcf\u5c42\u804c\u8d23\u5355\u4e00\u3001\u8fb9\u754c\u660e\u786e&#xff1a;<\/p>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502 Layer 6: \u63a5\u5165\u5c42 (Access Layer)                                      \u2502<br \/>\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510       \u2502<br \/>\n\u2502 \u2502 HTTP\/   \u2502 \u2502 gRPC    \u2502 \u2502 WebSocket\u2502 \u2502 Webhook \u2502 \u2502 SDK     \u2502       \u2502<br \/>\n\u2502 \u2502 REST    \u2502 \u2502 Server  \u2502 \u2502 Server   \u2502 \u2502 Handler \u2502 \u2502 Gateway \u2502       \u2502<br \/>\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518       \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502 Layer 5: \u534f\u8bae\u9002\u914d\u5c42 (Protocol Adaptation Layer)                      \u2502<br \/>\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u2502<br \/>\n\u2502 \u2502 Web Adapter  \u2502 \u2502 Feishu       \u2502 \u2502 DingTalk     \u2502 \u2502 Slack      \u2502  \u2502<br \/>\n\u2502 \u2502              \u2502 \u2502 Adapter      \u2502 \u2502 Adapter      \u2502 \u2502 Adapter    \u2502  \u2502<br \/>\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2502<br \/>\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u2502<br \/>\n\u2502 \u2502 WeCom Adapter\u2502 \u2502 Telegram     \u2502 \u2502 Discord      \u2502 \u2502 Email      \u2502  \u2502<br \/>\n\u2502 \u2502              \u2502 \u2502 Adapter      \u2502 \u2502 Adapter      \u2502 \u2502 Adapter    \u2502  \u2502<br \/>\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2502<br \/>\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                 \u2502<br \/>\n\u2502 \u2502 WhatsApp     \u2502 \u2502 Teams        \u2502 \u2502 Custom&#8230;    \u2502                 \u2502<br \/>\n\u2502 \u2502 Adapter      \u2502 \u2502 Adapter      \u2502 \u2502              \u2502                 \u2502<br \/>\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                 \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502 Layer 4: \u4f1a\u8bdd\u7ba1\u7406\u5c42 (Session Management Layer)                       \u2502<br \/>\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502<br \/>\n\u2502 \u2502 Session     \u2502 \u2502 Context       \u2502 \u2502 Session       \u2502 \u2502 TTL        \u2502 \u2502<br \/>\n\u2502 \u2502 Store       \u2502 \u2502 Compressor    \u2502 \u2502 Router        \u2502 \u2502 Manager    \u2502 \u2502<br \/>\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502 Layer 3: \u8def\u7531\u7f16\u6392\u5c42 (Routing &amp; Orchestration Layer)                  \u2502<br \/>\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u2502<br \/>\n\u2502 \u2502 Intent       \u2502 \u2502 Task         \u2502 \u2502 Memory       \u2502 \u2502 Safety     \u2502  \u2502<br \/>\n\u2502 \u2502 Detector     \u2502 \u2502 Orchestrator \u2502 \u2502 Scheduler    \u2502 \u2502 Sandbox    \u2502  \u2502<br \/>\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502 Layer 2: \u5de5\u5177\u8c03\u5ea6\u5c42 (Tool Orchestration Layer)                       \u2502<br \/>\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u2502<br \/>\n\u2502 \u2502 Tool         \u2502 \u2502 Permission   \u2502 \u2502 Tool         \u2502 \u2502 Audit      \u2502  \u2502<br \/>\n\u2502 \u2502 Registry     \u2502 \u2502 Checker      \u2502 \u2502 Dispatcher   \u2502 \u2502 Logger     \u2502  \u2502<br \/>\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502 Layer 1: \u57fa\u7840\u8bbe\u65bd\u5c42 (Infrastructure Layer)                           \u2502<br \/>\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u2502<br \/>\n\u2502 \u2502 Cache    \u2502 \u2502 Queue    \u2502 \u2502 Storage  \u2502 \u2502 Config   \u2502 \u2502 Monitor  \u2502  \u2502<br \/>\n\u2502 \u2502 (Redis)  \u2502 \u2502 (Kafka)  \u2502 \u2502 (S3\/DB)  \u2502 \u2502 Center   \u2502 \u2502 Agent    \u2502  \u2502<br \/>\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<h4>\u5404\u5c42\u804c\u8d23\u8be6\u89e3<\/h4>\n<p>Layer 6 \u2014 \u63a5\u5165\u5c42&#xff1a;\u8d1f\u8d23\u7f51\u7edc\u534f\u8bae\u7684\u63a5\u5165\u4e0e\u8fde\u63a5\u7ba1\u7406\u3002\u652f\u6301 HTTP\/REST\u3001gRPC\u3001WebSocket \u4e09\u79cd\u4e3b\u8981\u534f\u8bae&#xff0c;\u540c\u65f6\u63d0\u4f9b Webhook \u56de\u8c03\u7aef\u70b9\u548c SDK \u76f4\u8fde\u901a\u9053\u3002\u63a5\u5165\u5c42\u5b9e\u65bd TLS \u7ec8\u6b62\u3001\u8fde\u63a5\u6c60\u7ba1\u7406\u3001\u8bf7\u6c42\u5927\u5c0f\u9650\u5236\u7b49\u57fa\u7840\u7f51\u7edc\u7b56\u7565\u3002<\/p>\n<p>Layer 5 \u2014 \u534f\u8bae\u9002\u914d\u5c42&#xff1a;\u5c06\u5404\u6e20\u9053\u7684\u79c1\u6709\u534f\u8bae\u9002\u914d\u4e3a Gateway \u5185\u90e8\u7edf\u4e00\u6d88\u606f\u683c\u5f0f\u3002\u6bcf\u4e2a\u9002\u914d\u5668\u5b9e\u73b0\u6807\u51c6\u7684 ChannelAdapter SPI \u63a5\u53e3&#xff0c;\u8d1f\u8d23\u5165\u7ad9\u6d88\u606f\u89e3\u6790\u548c\u51fa\u7ad9\u6d88\u606f\u683c\u5f0f\u5316\u3002\u9002\u914d\u5668\u4e4b\u95f4\u5b8c\u5168\u9694\u79bb&#xff0c;\u4e92\u4e0d\u5f71\u54cd\u3002<\/p>\n<p>Layer 4 \u2014 \u4f1a\u8bdd\u7ba1\u7406\u5c42&#xff1a;\u7ef4\u62a4\u591a\u8f6e\u5bf9\u8bdd\u7684\u4e0a\u4e0b\u6587\u72b6\u6001\u3002Session Store \u8d1f\u8d23\u4f1a\u8bdd\u6570\u636e\u7684\u6301\u4e45\u5316\u4e0e\u7f13\u5b58&#xff1b;Context Compressor \u5728\u4e0a\u4e0b\u6587\u63a5\u8fd1 Token \u9884\u7b97\u65f6\u6267\u884c\u538b\u7f29&#xff1b;Session Router \u6839\u636e\u4f1a\u8bdd ID \u5c06\u8bf7\u6c42\u8def\u7531\u5230\u6b63\u786e\u7684\u5904\u7406\u8282\u70b9&#xff1b;TTL Manager \u7ba1\u7406\u4f1a\u8bdd\u7684\u751f\u547d\u5468\u671f\u8fc7\u671f\u3002<\/p>\n<p>Layer 3 \u2014 \u8def\u7531\u7f16\u6392\u5c42&#xff1a;Gateway \u7684\u5927\u8111\u3002Intent Detector \u8bc6\u522b\u7528\u6237\u610f\u56fe&#xff1b;Task Orchestrator \u6839\u636e\u610f\u56fe\u7f16\u6392\u4efb\u52a1\u6267\u884c\u8ba1\u5212&#xff1b;Memory Scheduler \u51b3\u5b9a\u4f55\u65f6\u8bfb\u5199\u8bb0\u5fc6&#xff1b;Safety Sandbox \u4e3a\u9ad8\u98ce\u9669\u64cd\u4f5c\u63d0\u4f9b\u9694\u79bb\u6267\u884c\u73af\u5883\u3002<\/p>\n<p>Layer 2 \u2014 \u5de5\u5177\u8c03\u5ea6\u5c42&#xff1a;\u7ba1\u7406\u6240\u6709\u53ef\u7528\u5de5\u5177\u7684\u6ce8\u518c\u3001\u53d1\u73b0\u3001\u8c03\u5ea6\u4e0e\u5ba1\u8ba1\u3002Tool Registry \u7ef4\u62a4\u5de5\u5177\u5143\u6570\u636e&#xff1b;Permission Checker \u6821\u9a8c\u8c03\u7528\u6743\u9650&#xff1b;Tool Dispatcher \u6267\u884c\u5b9e\u9645\u5de5\u5177\u8c03\u7528&#xff1b;Audit Logger \u8bb0\u5f55\u5168\u91cf\u8c03\u7528\u65e5\u5fd7\u3002<\/p>\n<p>Layer 1 \u2014 \u57fa\u7840\u8bbe\u65bd\u5c42&#xff1a;\u4e3a\u4e0a\u5c42\u63d0\u4f9b\u5206\u5e03\u5f0f\u7f13\u5b58\u3001\u6d88\u606f\u961f\u5217\u3001\u5bf9\u8c61\u5b58\u50a8\u3001\u914d\u7f6e\u7ba1\u7406\u548c\u76d1\u63a7\u4ee3\u7406\u7b49\u57fa\u7840\u80fd\u529b\u3002<\/p>\n<h3>1.5 \u6280\u672f\u9009\u578b\u6982\u89c8<\/h3>\n<table>\n<tr>\u7ec4\u4ef6\u6280\u672f\u9009\u578b\u9009\u578b\u7406\u7531<\/tr>\n<tbody>\n<tr>\n<td>\u5f00\u53d1\u8bed\u8a00<\/td>\n<td>Rust (\u6838\u5fc3) &#043; Python (\u5de5\u5177\u5c42)<\/td>\n<td>Rust \u63d0\u4f9b\u5185\u5b58\u5b89\u5168\u4e0e\u96f6\u6210\u672c\u62bd\u8c61&#xff1b;Python \u63d0\u4f9b\u5de5\u5177\u751f\u6001\u517c\u5bb9\u6027<\/td>\n<\/tr>\n<tr>\n<td>\u5f02\u6b65\u8fd0\u884c\u65f6<\/td>\n<td>Tokio<\/td>\n<td>\u4e1a\u754c\u6210\u719f\u7684 Rust \u5f02\u6b65\u8fd0\u884c\u65f6&#xff0c;\u652f\u6301\u9ad8\u5e76\u53d1 IO<\/td>\n<\/tr>\n<tr>\n<td>\u901a\u4fe1\u534f\u8bae<\/td>\n<td>gRPC (\u5185\u90e8) &#043; HTTP\/2 (\u5916\u90e8)<\/td>\n<td>gRPC \u63d0\u4f9b\u9ad8\u6548\u5185\u90e8\u901a\u4fe1&#xff1b;HTTP\/2 \u517c\u5bb9\u5916\u90e8\u5ba2\u6237\u7aef<\/td>\n<\/tr>\n<tr>\n<td>\u5e8f\u5217\u5316<\/td>\n<td>Protocol Buffers<\/td>\n<td>\u9ad8\u6548\u4e8c\u8fdb\u5236\u5e8f\u5217\u5316&#xff0c;\u8de8\u8bed\u8a00\u652f\u6301<\/td>\n<\/tr>\n<tr>\n<td>\u4f1a\u8bdd\u5b58\u50a8<\/td>\n<td>Redis Cluster<\/td>\n<td>\u4e9a\u6beb\u79d2\u7ea7\u8bfb\u5199&#xff0c;\u652f\u6301\u6301\u4e45\u5316\u4e0e\u96c6\u7fa4\u6a21\u5f0f<\/td>\n<\/tr>\n<tr>\n<td>\u6d88\u606f\u961f\u5217<\/td>\n<td>Apache Kafka<\/td>\n<td>\u9ad8\u541e\u5410\u91cf\u3001\u6301\u4e45\u5316\u3001\u652f\u6301\u7cbe\u786e\u4e00\u6b21\u6295\u9012<\/td>\n<\/tr>\n<tr>\n<td>\u914d\u7f6e\u4e2d\u5fc3<\/td>\n<td>etcd<\/td>\n<td>\u5f3a\u4e00\u81f4\u6027 KV \u5b58\u50a8&#xff0c;\u652f\u6301 Watch \u673a\u5236<\/td>\n<\/tr>\n<tr>\n<td>\u53ef\u89c2\u6d4b\u6027<\/td>\n<td>OpenTelemetry &#043; Jaeger &#043; Prometheus<\/td>\n<td>CNCF \u6807\u51c6&#xff0c;\u5168\u94fe\u8def\u8ffd\u8e2a&#043;\u6307\u6807&#043;\u65e5\u5fd7<\/td>\n<\/tr>\n<tr>\n<td>\u6c99\u7bb1\u5f15\u64ce<\/td>\n<td>Firecracker microVM<\/td>\n<td>AWS \u5f00\u6e90&#xff0c;\u6beb\u79d2\u7ea7\u542f\u52a8&#xff0c;\u5f3a\u9694\u79bb\u6027<\/td>\n<\/tr>\n<tr>\n<td>\u5de5\u5177\u534f\u8bae<\/td>\n<td>MCP (Model Context Protocol)<\/td>\n<td>Anthropic \u63d0\u51fa\u7684\u5f00\u653e\u6807\u51c6&#xff0c;\u751f\u6001\u4e30\u5bcc<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<h2>\u7b2c\u4e8c\u7ae0 \u4f1a\u8bdd\u7ba1\u7406\u5668\u6df1\u5ea6\u89e3\u6790<\/h2>\n<p>\u4f1a\u8bdd\u7ba1\u7406\u5668\u662f Gateway \u4e2d\u6700\u6838\u5fc3\u7684\u7ec4\u4ef6\u4e4b\u4e00&#xff0c;\u5b83\u627f\u62c5\u7740\u7ef4\u62a4\u591a\u8f6e\u5bf9\u8bdd\u4e0a\u4e0b\u6587\u5b8c\u6574\u6027\u3001\u4fdd\u969c\u4f1a\u8bdd\u9694\u79bb\u6027\u3001\u4f18\u5316\u4e0a\u4e0b\u6587\u7a97\u53e3\u5229\u7528\u7387\u7684\u5173\u952e\u804c\u8d23\u3002\u5728\u4e00\u4e2a\u5178\u578b\u7684 Agent \u7cfb\u7edf\u4e2d&#xff0c;\u4f1a\u8bdd\u7ba1\u7406\u7684\u8d28\u91cf\u76f4\u63a5\u51b3\u5b9a\u4e86\u7528\u6237\u4ea4\u4e92\u7684\u8fde\u8d2f\u6027\u548c\u63a8\u7406\u8d28\u91cf\u7684\u4e0a\u9650\u3002<\/p>\n<h3>2.1 \u591a\u8f6e\u5bf9\u8bdd\u4e0a\u4e0b\u6587\u7ef4\u62a4<\/h3>\n<h4>2.1.1 \u4e0a\u4e0b\u6587\u6570\u636e\u6a21\u578b<\/h4>\n<p>Hermes Agent \u7684\u4f1a\u8bdd\u4e0a\u4e0b\u6587\u91c7\u7528\u5206\u5c42\u7ed3\u6784\u8fdb\u884c\u7ec4\u7ec7&#xff0c;\u6bcf\u4e00\u5c42\u627f\u8f7d\u4e0d\u540c\u7c92\u5ea6\u7684\u4fe1\u606f&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u4f1a\u8bdd\u4e0a\u4e0b\u6587\u7684\u6838\u5fc3\u6570\u636e\u7ed3\u6784<\/span><br \/>\n<span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">SessionContext<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4f1a\u8bdd\u552f\u4e00\u6807\u8bc6<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> session_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7528\u6237\u6807\u8bc6<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> user_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">UserId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6e20\u9053\u6765\u6e90<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> channel<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4f1a\u8bdd\u521b\u5efa\u65f6\u95f4<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> created_at<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">DateTime<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6700\u540e\u6d3b\u8dc3\u65f6\u95f4<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> last_active_at<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">DateTime<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4f1a\u8bdd\u72b6\u6001<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> status<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">SessionStatus<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5bf9\u8bdd\u6d88\u606f\u5e8f\u5217&#xff08;\u6309\u65f6\u95f4\u6392\u5e8f&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> messages<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Message<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4f1a\u8bdd\u7ea7\u5143\u6570\u636e<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> metadata<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">SessionMetadata<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u538b\u7f29\u540e\u7684\u6458\u8981&#xff08;\u5f53\u4e0a\u4e0b\u6587\u88ab\u538b\u7f29\u65f6\u586b\u5145&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> compressed_summary<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Summary<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6d3b\u8dc3\u5de5\u5177\u8c03\u7528\u6808<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> active_tool_calls<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolCallContext<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4f1a\u8bdd\u7ea7\u8bb0\u5fc6\u5f15\u7528<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> memory_refs<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">MemoryRef<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">Message<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6d88\u606f\u552f\u4e00ID<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> message_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">MessageId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6d88\u606f\u89d2\u8272&#xff1a;user \/ assistant \/ system \/ tool<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> role<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">MessageRole<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6d88\u606f\u5185\u5bb9&#xff08;\u652f\u6301\u591a\u6a21\u6001&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> content<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">MessageContent<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6d88\u606f\u65f6\u95f4\u6233<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> timestamp<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">DateTime<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6d88\u606f\u5143\u6570\u636e&#xff08;\u6a21\u578bID\u3001Token\u6d88\u8017\u3001\u5ef6\u8fdf\u7b49&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> metadata<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">MessageMetadata<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5173\u8054\u7684\u5de5\u5177\u8c03\u7528&#xff08;\u5982\u679c\u6709&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> tool_calls<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolCall<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6d88\u606f\u72b6\u6001<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> status<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">MessageStatus<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">MessageContent<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7eaf\u6587\u672c<\/span><br \/>\n    <span class=\"token class-name\">Text<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u591a\u6a21\u6001\u5185\u5bb9&#xff08;\u6587\u672c&#043;\u56fe\u7247&#043;\u6587\u4ef6\u7b49&#xff09;<\/span><br \/>\n    <span class=\"token class-name\">Multimodal<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        text<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        images<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ImageContent<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        files<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">FileContent<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        attachments<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Attachment<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5de5\u5177\u8c03\u7528\u7ed3\u679c<\/span><br \/>\n    <span class=\"token class-name\">ToolResult<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        tool_call_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        result<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        is_error<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">SessionMetadata<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5f53\u524d\u4f7f\u7528\u7684\u6a21\u578b<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> current_model<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7d2f\u8ba1 Token \u6d88\u8017<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> total_tokens_consumed<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5bf9\u8bdd\u8f6e\u6b21<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> turn_count<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u32<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4f1a\u8bdd\u4e3b\u9898&#xff08;\u7531\u610f\u56fe\u8bc6\u522b\u81ea\u52a8\u63d0\u53d6&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> topic<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7528\u6237\u504f\u597d&#xff08;\u4ece\u8bb0\u5fc6\u7cfb\u7edf\u52a0\u8f7d&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> user_preferences<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u81ea\u5b9a\u4e49\u6807\u7b7e<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> tags<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>2.1.2 \u4e0a\u4e0b\u6587\u589e\u91cf\u66f4\u65b0\u673a\u5236<\/h4>\n<p>\u6bcf\u6b21\u6d88\u606f\u4ea4\u4e92\u540e&#xff0c;\u4f1a\u8bdd\u4e0a\u4e0b\u6587\u9700\u8981\u8fdb\u884c\u589e\u91cf\u66f4\u65b0\u3002Hermes Agent \u91c7\u7528 Write-Ahead Log (WAL) \u673a\u5236\u4fdd\u8bc1\u4e0a\u4e0b\u6587\u66f4\u65b0\u7684\u539f\u5b50\u6027\u548c\u6301\u4e45\u6027&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u4f1a\u8bdd\u4e0a\u4e0b\u6587\u589e\u91cf\u66f4\u65b0\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ContextUpdater<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    session_store<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SessionStore<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    wal<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">WriteAheadLog<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    compressor<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ContextCompressor<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">ContextUpdater<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u8ffd\u52a0\u65b0\u6d88\u606f\u5230\u4f1a\u8bdd\u4e0a\u4e0b\u6587<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">append_message<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        session_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        message<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Message<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">UpdateResult<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">SessionError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ 1. \u5199\u5165 WAL&#xff0c;\u4fdd\u8bc1\u539f\u5b50\u6027<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> wal_entry <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">WalEntry<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">AppendMessage<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            session_id<span class=\"token punctuation\">:<\/span> session_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            message<span class=\"token punctuation\">:<\/span> message<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            timestamp<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Utc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>wal<span class=\"token punctuation\">.<\/span><span class=\"token function\">append<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>wal_entry<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 2. \u66f4\u65b0\u5185\u5b58\u4e2d\u7684\u4f1a\u8bdd\u4e0a\u4e0b\u6587<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> session <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>session_store<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>session_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        session<span class=\"token punctuation\">.<\/span>messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span>message<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        session<span class=\"token punctuation\">.<\/span>metadata<span class=\"token punctuation\">.<\/span>turn_count <span class=\"token operator\">&#043;&#061;<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        session<span class=\"token punctuation\">.<\/span>last_active_at <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Utc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 3. \u8ba1\u7b97 Token \u4f7f\u7528\u91cf<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> token_count <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">estimate_tokens<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>session<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> token_budget <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get_token_budget<\/span><span class=\"token punctuation\">(<\/span>session_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 4. \u5224\u65ad\u662f\u5426\u9700\u8981\u538b\u7f29<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> needs_compression <span class=\"token operator\">&#061;<\/span> token_count <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">f64<\/span> <span class=\"token operator\">\/<\/span> token_budget <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">f64<\/span><br \/>\n            <span class=\"token operator\">&gt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>compressor<span class=\"token punctuation\">.<\/span>compression_threshold<span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> needs_compression <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> compressed <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>compressor<span class=\"token punctuation\">.<\/span><span class=\"token function\">compress<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>session<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            session<span class=\"token punctuation\">.<\/span>compressed_summary <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>compressed<span class=\"token punctuation\">.<\/span>summary<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token comment\">\/\/ \u4fdd\u7559\u6700\u8fd1 N \u6761\u539f\u59cb\u6d88\u606f &#043; \u538b\u7f29\u6458\u8981<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> retain_count <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>compressor<span class=\"token punctuation\">.<\/span>recent_message_window<span class=\"token punctuation\">;<\/span><br \/>\n            session<span class=\"token punctuation\">.<\/span>messages <span class=\"token operator\">&#061;<\/span> session<span class=\"token punctuation\">.<\/span>messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">split_off<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                session<span class=\"token punctuation\">.<\/span>messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">saturating_sub<\/span><span class=\"token punctuation\">(<\/span>retain_count<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 5. \u6301\u4e45\u5316\u5230 Session Store<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>session_store<span class=\"token punctuation\">.<\/span><span class=\"token function\">put<\/span><span class=\"token punctuation\">(<\/span>session_id<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span>session<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 6. \u6807\u8bb0 WAL \u6761\u76ee\u4e3a\u5df2\u5b8c\u6210<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>wal<span class=\"token punctuation\">.<\/span><span class=\"token function\">mark_complete<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>wal_entry<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">UpdateResult<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            session_id<span class=\"token punctuation\">:<\/span> session_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            token_count<span class=\"token punctuation\">,<\/span><br \/>\n            token_budget<span class=\"token punctuation\">,<\/span><br \/>\n            compressed<span class=\"token punctuation\">:<\/span> needs_compression<span class=\"token punctuation\">,<\/span><br \/>\n            turn_count<span class=\"token punctuation\">:<\/span> session<span class=\"token punctuation\">.<\/span>metadata<span class=\"token punctuation\">.<\/span>turn_count<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>2.1.3 \u4e0a\u4e0b\u6587\u7248\u672c\u63a7\u5236<\/h4>\n<p>\u4e3a\u4e86\u652f\u6301\u4f1a\u8bdd\u56de\u6eda\u548c\u8c03\u8bd5&#xff0c;\u4f1a\u8bdd\u7ba1\u7406\u5668\u4e3a\u6bcf\u6b21\u4e0a\u4e0b\u6587\u53d8\u66f4\u7ef4\u62a4\u7248\u672c\u53f7&#xff1a;<\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">SessionVersion<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7248\u672c\u53f7&#xff08;\u5355\u8c03\u9012\u589e&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> version<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u53d8\u66f4\u7c7b\u578b<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> change_type<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ChangeType<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u53d8\u66f4\u65f6\u95f4<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> timestamp<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">DateTime<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u53d8\u66f4\u524d\u5feb\u7167\u7684\u5f15\u7528&#xff08;\u4ec5\u4fdd\u7559\u6700\u8fd1 N \u4e2a\u7248\u672c&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> parent_version<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">u64<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">ChangeType<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">MessageAppended<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">ContextCompressed<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">ToolCallStarted<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">ToolCallCompleted<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">MetadataUpdated<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">SessionResumed<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">SessionForked<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u7248\u672c\u63a7\u5236\u64cd\u4f5c\u63a5\u53e3<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">trait<\/span> <span class=\"token type-definition class-name\">SessionVersioning<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u83b7\u53d6\u5f53\u524d\u7248\u672c<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">current_version<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> session_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u56de\u6eda\u5230\u6307\u5b9a\u7248\u672c<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">rollback_to<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        session_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        target_version<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">SessionError<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u521b\u5efa\u4f1a\u8bdd\u5206\u652f&#xff08;\u7528\u4e8e\u5e76\u884c\u63a2\u7d22&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">fork<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        session_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        at_version<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">SessionError<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u83b7\u53d6\u53d8\u66f4\u5386\u53f2<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">changelog<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        session_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        from<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">u64<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        to<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">u64<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SessionVersion<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u4e0a\u4e0b\u6587\u7248\u672c\u63a7\u5236\u7684\u6838\u5fc3\u5e94\u7528\u573a\u666f\u5305\u62ec&#xff1a;<\/p>\n<li>\u4f1a\u8bdd\u56de\u6eda&#xff1a;\u5f53 Agent \u6267\u884c\u4e86\u9519\u8bef\u7684\u5de5\u5177\u8c03\u7528\u6216\u4ea7\u751f\u4e86\u4e0d\u7406\u60f3\u7684\u56de\u7b54\u65f6&#xff0c;\u53ef\u4ee5\u56de\u6eda\u5230\u4e4b\u524d\u7684\u4e0a\u4e0b\u6587\u72b6\u6001&#xff0c;\u91cd\u65b0\u6267\u884c<\/li>\n<li>\u5e76\u884c\u63a2\u7d22&#xff1a;\u4ece\u540c\u4e00\u4f1a\u8bdd\u8282\u70b9\u5206\u53c9\u51fa\u591a\u4e2a\u5206\u652f&#xff0c;\u6bcf\u4e2a\u5206\u652f\u5c1d\u8bd5\u4e0d\u540c\u7684\u7b56\u7565&#xff0c;\u6700\u7ec8\u9009\u62e9\u6700\u4f18\u7ed3\u679c\u5408\u5e76\u56de\u4e3b\u7ebf<\/li>\n<li>\u8c03\u8bd5\u4e0e\u5ba1\u8ba1&#xff1a;\u901a\u8fc7\u53d8\u66f4\u5386\u53f2\u7cbe\u786e\u8ffd\u8e2a\u4f1a\u8bdd\u4e0a\u4e0b\u6587\u7684\u6f14\u53d8\u8fc7\u7a0b&#xff0c;\u5b9a\u4f4d\u95ee\u9898\u6839\u56e0<\/li>\n<li>A\/B \u6d4b\u8bd5&#xff1a;\u5bf9\u540c\u4e00\u7528\u6237\u8f93\u5165&#xff0c;\u5728\u4e0d\u540c\u7248\u672c\u7684\u4e0a\u4e0b\u6587\u4e0a\u6d4b\u8bd5\u4e0d\u540c\u7684\u6a21\u578b\u6216\u63d0\u793a\u8bcd\u7b56\u7565<\/li>\n<h3>2.2 \u4f1a\u8bdd ID \u8def\u7531\u673a\u5236<\/h3>\n<h4>2.2.1 \u4f1a\u8bdd ID \u751f\u6210\u7b56\u7565<\/h4>\n<p>\u4f1a\u8bdd ID \u662f Gateway \u8def\u7531\u7684\u6838\u5fc3\u6807\u8bc6\u3002Hermes Agent \u91c7\u7528 Snowflake \u53d8\u4f53 \u751f\u6210\u5168\u5c40\u552f\u4e00\u3001\u65f6\u95f4\u6709\u5e8f\u7684\u4f1a\u8bdd ID&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u4f1a\u8bdd ID \u7ed3\u6784&#xff08;128\u4f4d&#xff09;<\/span><br \/>\n<span class=\"token comment\">\/\/\/ | 1\u4f4d\u7b26\u53f7 | 41\u4f4d\u65f6\u95f4\u6233 | 10\u4f4d\u673a\u5668ID | 10\u4f4d\u6e20\u9053ID | 66\u4f4d\u5e8f\u5217\u53f7 |<\/span><br \/>\n<span class=\"token attribute attr-name\">#[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">SessionId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">u128<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">SessionId<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">new<\/span><span class=\"token punctuation\">(<\/span>machine_id<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u16<\/span><span class=\"token punctuation\">,<\/span> channel_id<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u16<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token keyword\">Self<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> timestamp <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">SystemTime<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">duration_since<\/span><span class=\"token punctuation\">(<\/span><span class=\"token constant\">UNIX_EPOCH<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">as_millis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> sequence <span class=\"token operator\">&#061;<\/span> <span class=\"token constant\">SEQUENCE_COUNTER<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">fetch_add<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Ordering<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">SeqCst<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> id <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>timestamp <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">u128<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&lt;&lt;<\/span> <span class=\"token number\">87<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token operator\">|<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>machine_id <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">u128<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&lt;&lt;<\/span> <span class=\"token number\">77<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token operator\">|<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>channel_id <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">u128<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&lt;&lt;<\/span> <span class=\"token number\">67<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token operator\">|<\/span> <span class=\"token punctuation\">(<\/span>sequence <span class=\"token operator\">&amp;<\/span> <span class=\"token number\">0x7FFFFFFFFFFFFF<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">(<\/span>id<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u4ece\u4f1a\u8bdd ID \u63d0\u53d6\u65f6\u95f4\u6233<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">timestamp<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token keyword\">u64<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token punctuation\">(<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token number\">0<\/span> <span class=\"token operator\">&gt;&gt;<\/span> <span class=\"token number\">87<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">u64<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u4ece\u4f1a\u8bdd ID \u63d0\u53d6\u673a\u5668 ID&#xff08;\u7528\u4e8e\u8def\u7531&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">machine_id<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token keyword\">u16<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token number\">0<\/span> <span class=\"token operator\">&gt;&gt;<\/span> <span class=\"token number\">77<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&amp;<\/span> <span class=\"token number\">0x3FF<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">u16<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u4ece\u4f1a\u8bdd ID \u63d0\u53d6\u6e20\u9053 ID<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">channel_id<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token keyword\">u16<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token number\">0<\/span> <span class=\"token operator\">&gt;&gt;<\/span> <span class=\"token number\">67<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&amp;<\/span> <span class=\"token number\">0x3FF<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">u16<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u4f1a\u8bdd ID \u7684\u8bbe\u8ba1\u8981\u70b9&#xff1a;<\/p>\n<ul>\n<li>\u65f6\u95f4\u6709\u5e8f&#xff1a;41\u4f4d\u65f6\u95f4\u6233\u4f7f\u5f97\u4f1a\u8bdd ID \u5929\u7136\u6309\u521b\u5efa\u65f6\u95f4\u6392\u5e8f&#xff0c;\u6709\u5229\u4e8e\u8303\u56f4\u67e5\u8be2\u548c\u65f6\u95f4\u7a97\u53e3\u8fc7\u6ee4<\/li>\n<li>\u673a\u5668\u53ef\u8def\u7531&#xff1a;10\u4f4d\u673a\u5668 ID \u76f4\u63a5\u7f16\u7801\u5728\u4f1a\u8bdd ID \u4e2d&#xff0c;\u65e0\u9700\u989d\u5916\u67e5\u8868\u5373\u53ef\u786e\u5b9a\u4f1a\u8bdd\u5f52\u5c5e\u8282\u70b9<\/li>\n<li>\u6e20\u9053\u53ef\u8ffd\u6eaf&#xff1a;10\u4f4d\u6e20\u9053 ID \u4f7f\u5f97\u4ece\u4f1a\u8bdd ID \u5373\u53ef\u8bc6\u522b\u6765\u6e90\u6e20\u9053&#xff0c;\u4fbf\u4e8e\u6e20\u9053\u7ef4\u5ea6\u7684\u7edf\u8ba1\u548c\u6545\u969c\u6392\u67e5<\/li>\n<li>\u5e8f\u5217\u53f7\u5145\u8db3&#xff1a;66\u4f4d\u5e8f\u5217\u53f7\u7406\u8bba\u4e0a\u652f\u6301\u6bcf\u6beb\u79d2 2^66 \u4e2a\u4f1a\u8bdd\u521b\u5efa&#xff0c;\u6c38\u8fdc\u4e0d\u4f1a\u6ea2\u51fa<\/li>\n<\/ul>\n<h4>2.2.2 \u4e00\u81f4\u6027\u54c8\u5e0c\u8def\u7531<\/h4>\n<p>Gateway \u96c6\u7fa4\u4e2d&#xff0c;\u4f1a\u8bdd\u6570\u636e\u5206\u5e03\u5728\u591a\u4e2a\u8282\u70b9\u4e0a\u3002\u91c7\u7528\u4e00\u81f4\u6027\u54c8\u5e0c\u73af\u786e\u4fdd\u4f1a\u8bdd\u4eb2\u548c\u6027\u2014\u2014\u540c\u4e00\u4e2a\u4f1a\u8bdd\u7684\u8bf7\u6c42\u59cb\u7ec8\u8def\u7531\u5230\u540c\u4e00\u8282\u70b9&#xff1a;<\/p>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502                    \u4e00\u81f4\u6027\u54c8\u5e0c\u8def\u7531\u73af                                     \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502                        0 \/ 2^128                                     \u2502<br \/>\n\u2502                          \u2502                                           \u2502<br \/>\n\u2502            Node A \u25cf\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u25cf Node D                             \u2502<br \/>\n\u2502            (hash:0x3F..) \u2502    (hash:0xC0..)                          \u2502<br \/>\n\u2502                   \u2571      \u2502      \u2572                                   \u2502<br \/>\n\u2502                  \u2571       \u2502       \u2572                                  \u2502<br \/>\n\u2502                 \u2571        \u2502        \u2572                                 \u2502<br \/>\n\u2502    Node B \u25cf\u2500\u2500\u2500\u2500\u2500\u2571         \u2502         \u2572\u2500\u2500\u2500\u2500\u2500\u25cf Node C                   \u2502<br \/>\n\u2502  (hash:0x10..)            \u2502           (hash:0x80..)                  \u2502<br \/>\n\u2502                          \u2502                                           \u2502<br \/>\n\u2502     Session ID hash \u2500\u2500&gt; \u6cbf\u987a\u65f6\u9488\u627e\u5230\u7684\u7b2c\u4e00\u4e2a\u8282\u70b9                        \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502   \u865a\u62df\u8282\u70b9 (Virtual Nodes):                                           \u2502<br \/>\n\u2502   Node A: v1, v2, v3, v4, v5 (5\u4e2a\u865a\u62df\u8282\u70b9)                            \u2502<br \/>\n\u2502   Node B: v1, v2, v3, v4, v5 (5\u4e2a\u865a\u62df\u8282\u70b9)                            \u2502<br \/>\n\u2502   Node C: v1, v2, v3, v4, v5 (5\u4e2a\u865a\u62df\u8282\u70b9)                            \u2502<br \/>\n\u2502   Node D: v1, v2, v3, v4, v5 (5\u4e2a\u865a\u62df\u8282\u70b9)                            \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502   \u6545\u969c\u8f6c\u79fb: Node B \u5b95\u673a \u2192 \u5176\u865a\u62df\u8282\u70b9\u987a\u65f6\u9488\u8fc1\u79fb\u5230 Node C \u548c Node D       \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<p><span class=\"token comment\">\/\/\/ \u4e00\u81f4\u6027\u54c8\u5e0c\u8def\u7531\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ConsistentHashRouter<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u54c8\u5e0c\u73af&#xff1a;SortedMap&lt;Hash, NodeId&gt;<\/span><br \/>\n    ring<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">BTreeMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">u128<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">NodeId<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u865a\u62df\u8282\u70b9\u6570<\/span><br \/>\n    virtual_nodes<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u8282\u70b9\u5217\u8868<\/span><br \/>\n    nodes<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">NodeId<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">NodeInfo<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">ConsistentHashRouter<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6839\u636e\u4f1a\u8bdd ID \u8def\u7531\u5230\u76ee\u6807\u8282\u70b9<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">route<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> session_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">NodeId<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> ring <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>ring<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> hash <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">hash<\/span><span class=\"token punctuation\">(<\/span>session_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u6cbf\u987a\u65f6\u9488\u627e\u5230\u7b2c\u4e00\u4e2a\u8282\u70b9<\/span><br \/>\n        <span class=\"token keyword\">match<\/span> ring<span class=\"token punctuation\">.<\/span><span class=\"token function\">range<\/span><span class=\"token punctuation\">(<\/span>hash<span class=\"token punctuation\">..<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">next<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>_<span class=\"token punctuation\">,<\/span> node_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token operator\">*<\/span>node_id<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">None<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token comment\">\/\/ \u73af\u56de\u5230\u7b2c\u4e00\u4e2a\u8282\u70b9<\/span><br \/>\n                ring<span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">next<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span><span class=\"token punctuation\">(<\/span>_<span class=\"token punctuation\">,<\/span> id<span class=\"token punctuation\">)<\/span><span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token operator\">*<\/span>id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u83b7\u53d6\u4f1a\u8bdd\u7684\u5907\u7528\u8282\u70b9&#xff08;\u7528\u4e8e\u6545\u969c\u8f6c\u79fb&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">get_backup_nodes<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        session_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        count<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">NodeId<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> ring <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>ring<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> hash <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">hash<\/span><span class=\"token punctuation\">(<\/span>session_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> backups <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> seen <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">HashSet<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span>_<span class=\"token punctuation\">,<\/span> node_id<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">in<\/span> ring<span class=\"token punctuation\">.<\/span><span class=\"token function\">range<\/span><span class=\"token punctuation\">(<\/span>hash<span class=\"token punctuation\">..<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">chain<\/span><span class=\"token punctuation\">(<\/span>ring<span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token operator\">!<\/span>seen<span class=\"token punctuation\">.<\/span><span class=\"token function\">contains<\/span><span class=\"token punctuation\">(<\/span>node_id<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                seen<span class=\"token punctuation\">.<\/span><span class=\"token function\">insert<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">*<\/span>node_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                backups<span class=\"token punctuation\">.<\/span><span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">*<\/span>node_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token keyword\">if<\/span> backups<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> count <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">break<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n        backups<br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u8282\u70b9\u52a0\u5165\u96c6\u7fa4<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">add_node<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> node_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">NodeId<\/span><span class=\"token punctuation\">,<\/span> node_info<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">NodeInfo<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> ring <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>ring<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> nodes <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>nodes<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        nodes<span class=\"token punctuation\">.<\/span><span class=\"token function\">insert<\/span><span class=\"token punctuation\">(<\/span>node_id<span class=\"token punctuation\">,<\/span> node_info<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u6dfb\u52a0\u865a\u62df\u8282\u70b9<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> i <span class=\"token keyword\">in<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">..<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>virtual_nodes <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> vhash <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">hash_with_suffix<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>node_id<span class=\"token punctuation\">,<\/span> i<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            ring<span class=\"token punctuation\">.<\/span><span class=\"token function\">insert<\/span><span class=\"token punctuation\">(<\/span>vhash<span class=\"token punctuation\">,<\/span> node_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u8282\u70b9\u79bb\u5f00\u96c6\u7fa4<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">remove_node<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> node_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">NodeId<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> ring <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>ring<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> nodes <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>nodes<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        nodes<span class=\"token punctuation\">.<\/span><span class=\"token function\">remove<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>node_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> to_remove<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">u128<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&#061;<\/span> ring<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">filter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span><span class=\"token punctuation\">(<\/span>_<span class=\"token punctuation\">,<\/span> id<span class=\"token punctuation\">)<\/span><span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token operator\">*<\/span><span class=\"token operator\">*<\/span>id <span class=\"token operator\">&#061;&#061;<\/span> node_id<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span><span class=\"token punctuation\">(<\/span>h<span class=\"token punctuation\">,<\/span> _<span class=\"token punctuation\">)<\/span><span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token operator\">*<\/span>h<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">for<\/span> h <span class=\"token keyword\">in<\/span> to_remove <span class=\"token punctuation\">{<\/span><br \/>\n            ring<span class=\"token punctuation\">.<\/span><span class=\"token function\">remove<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>h<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u4e00\u81f4\u6027\u54c8\u5e0c\u8def\u7531\u7684\u6838\u5fc3\u4f18\u52bf\u5728\u4e8e\u6700\u5c0f\u5316\u8282\u70b9\u53d8\u66f4\u65f6\u7684\u6570\u636e\u8fc1\u79fb\u3002\u5f53\u96c6\u7fa4\u4e2d\u589e\u52a0\u6216\u51cf\u5c11\u4e00\u4e2a\u8282\u70b9\u65f6&#xff0c;\u5e73\u5747\u53ea\u6709 1\/N&#xff08;N\u4e3a\u8282\u70b9\u6570&#xff09;\u7684\u4f1a\u8bdd\u9700\u8981\u8fc1\u79fb&#xff0c;\u800c\u975e\u5168\u90e8\u91cd\u65b0\u5206\u5e03\u3002\u6bcf\u4e2a\u7269\u7406\u8282\u70b9\u914d\u7f6e 5-10 \u4e2a\u865a\u62df\u8282\u70b9&#xff0c;\u53ef\u4ee5\u8fdb\u4e00\u6b65\u5747\u8861\u6570\u636e\u5206\u5e03&#xff0c;\u907f\u514d\u70ed\u70b9\u95ee\u9898\u3002<\/p>\n<h4>2.2.3 \u4f1a\u8bdd\u4eb2\u548c\u6027\u4e0e\u8de8\u8282\u70b9\u8fc1\u79fb<\/h4>\n<p>\u5f53\u6301\u6709\u67d0\u4f1a\u8bdd\u7684\u8282\u70b9\u53d1\u751f\u6545\u969c\u65f6&#xff0c;Gateway \u9700\u8981\u5c06\u8be5\u4f1a\u8bdd\u8fc1\u79fb\u5230\u5907\u7528\u8282\u70b9\u3002\u8fc1\u79fb\u8fc7\u7a0b\u9700\u8981\u4fdd\u8bc1\u4e09\u4e2a\u5173\u952e\u5c5e\u6027&#xff1a;<\/p>\n<li>\u96f6\u4e22\u5931&#xff1a;\u4f1a\u8bdd\u6570\u636e\u5fc5\u987b\u5b8c\u6574\u8fc1\u79fb&#xff0c;\u5305\u62ec\u6240\u6709\u6d88\u606f\u5386\u53f2\u548c\u5143\u6570\u636e<\/li>\n<li>\u6700\u5c0f\u4e2d\u65ad&#xff1a;\u8fc1\u79fb\u671f\u95f4\u7684\u8bf7\u6c42\u88ab\u6682\u5b58&#xff0c;\u8fc1\u79fb\u5b8c\u6210\u540e\u7acb\u5373\u5904\u7406<\/li>\n<li>\u5e42\u7b49\u6027&#xff1a;\u8fc1\u79fb\u8fc7\u7a0b\u53ef\u5b89\u5168\u91cd\u8bd5&#xff0c;\u4e0d\u4f1a\u4ea7\u751f\u91cd\u590d\u6570\u636e<\/li>\n<p><span class=\"token comment\">\/\/\/ \u4f1a\u8bdd\u8fc1\u79fb\u7ba1\u7406\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">SessionMigrationManager<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    router<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ConsistentHashRouter<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    session_store<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SessionStore<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    migration_queue<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">MigrationQueue<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">SessionMigrationManager<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6267\u884c\u4f1a\u8bdd\u8fc1\u79fb<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">migrate_session<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        session_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        from_node<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">NodeId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        to_node<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">NodeId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">MigrationResult<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">MigrationError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token namespace\">tracing<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">info!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            session_id <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">%<\/span>session_id<span class=\"token punctuation\">,<\/span><br \/>\n            from <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">%<\/span>from_node<span class=\"token punctuation\">,<\/span><br \/>\n            to <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">%<\/span>to_node<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;Starting session migration&#034;<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 1. \u5728\u6e90\u8282\u70b9\u6807\u8bb0\u4f1a\u8bdd\u4e3a\u300c\u8fc1\u79fb\u4e2d\u300d\u72b6\u6001<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>session_store<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">set_migration_state<\/span><span class=\"token punctuation\">(<\/span>session_id<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">MigrationState<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">InProgress<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 2. \u4ece\u6e90\u8282\u70b9\u8bfb\u53d6\u5b8c\u6574\u4f1a\u8bdd\u6570\u636e<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> session_data <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>session_store<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">get_full_session<\/span><span class=\"token punctuation\">(<\/span>session_id<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 3. \u5c06\u4f1a\u8bdd\u6570\u636e\u5199\u5165\u76ee\u6807\u8282\u70b9<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>session_store<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">put_to_node<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>to_node<span class=\"token punctuation\">,<\/span> session_id<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span>session_data<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 4. \u9a8c\u8bc1\u6570\u636e\u5b8c\u6574\u6027<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> verify_data <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>session_store<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">get_from_node<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>to_node<span class=\"token punctuation\">,<\/span> session_id<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> verify_data<span class=\"token punctuation\">.<\/span>version <span class=\"token operator\">!&#061;<\/span> session_data<span class=\"token punctuation\">.<\/span>version <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Err<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">MigrationError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">VerificationFailed<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 5. \u66f4\u65b0\u8def\u7531\u8868<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>router<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">update_session_route<\/span><span class=\"token punctuation\">(<\/span>session_id<span class=\"token punctuation\">,<\/span> to_node<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 6. \u4ece\u6e90\u8282\u70b9\u5220\u9664\u65e7\u6570\u636e<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>session_store<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">delete_from_node<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>from_node<span class=\"token punctuation\">,<\/span> session_id<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 7. \u6807\u8bb0\u8fc1\u79fb\u5b8c\u6210<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>session_store<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">set_migration_state<\/span><span class=\"token punctuation\">(<\/span>session_id<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">MigrationState<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Completed<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token namespace\">tracing<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">info!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            session_id <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">%<\/span>session_id<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;Session migration completed successfully&#034;<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">MigrationResult<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            session_id<span class=\"token punctuation\">:<\/span> session_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            from_node<span class=\"token punctuation\">,<\/span><br \/>\n            to_node<span class=\"token punctuation\">,<\/span><br \/>\n            duration<span class=\"token punctuation\">:<\/span> session_data<span class=\"token punctuation\">.<\/span>messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u4f1a\u8bdd\u8fc1\u79fb\u7684\u89e6\u53d1\u573a\u666f\u5305\u62ec&#xff1a;<\/p>\n<table>\n<tr>\u89e6\u53d1\u6761\u4ef6\u8fc1\u79fb\u7b56\u7565\u9884\u671f\u4e2d\u65ad\u65f6\u95f4<\/tr>\n<tbody>\n<tr>\n<td>\u8282\u70b9\u786c\u4ef6\u6545\u969c<\/td>\n<td>\u81ea\u52a8\u6545\u969c\u8f6c\u79fb&#xff0c;\u4ece Redis \u526f\u672c\u6062\u590d<\/td>\n<td>&lt; 3\u79d2<\/td>\n<\/tr>\n<tr>\n<td>\u8282\u70b9\u6eda\u52a8\u5347\u7ea7<\/td>\n<td>\u4f18\u96c5\u8fc1\u79fb&#xff0c;\u5148\u8fc1\u79fb\u540e\u4e0b\u7ebf<\/td>\n<td>&lt; 1\u79d2<\/td>\n<\/tr>\n<tr>\n<td>\u96c6\u7fa4\u6269\u5bb9<\/td>\n<td>\u65b0\u8282\u70b9\u52a0\u5165\u89e6\u53d1\u6570\u636e\u518d\u5e73\u8861<\/td>\n<td>0&#xff08;\u540e\u53f0\u5f02\u6b65&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>\u8d1f\u8f7d\u4e0d\u5747<\/td>\n<td>\u70ed\u70b9\u4f1a\u8bdd\u8fc1\u79fb\u5230\u7a7a\u95f2\u8282\u70b9<\/td>\n<td>&lt; 2\u79d2<\/td>\n<\/tr>\n<tr>\n<td>\u624b\u52a8\u8fd0\u7ef4<\/td>\n<td>\u7ba1\u7406\u5458\u89e6\u53d1\u6307\u5b9a\u4f1a\u8bdd\u8fc1\u79fb<\/td>\n<td>&lt; 1\u79d2<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>2.3 \u4e0a\u4e0b\u6587\u7a97\u53e3\u538b\u7f29\u7b56\u7565<\/h3>\n<p>\u968f\u7740\u5bf9\u8bdd\u8f6e\u6b21\u589e\u52a0&#xff0c;\u4e0a\u4e0b\u6587 Token \u6570\u4f1a\u9010\u6e10\u903c\u8fd1\u751a\u81f3\u8d85\u51fa\u6a21\u578b\u7684\u6700\u5927\u4e0a\u4e0b\u6587\u7a97\u53e3\u3002Hermes Agent \u5b9e\u73b0\u4e86\u591a\u7ea7\u538b\u7f29\u7b56\u7565&#xff0c;\u5728\u4fdd\u7559\u5173\u952e\u4fe1\u606f\u7684\u540c\u65f6\u63a7\u5236 Token \u6d88\u8017\u3002<\/p>\n<h4>2.3.1 \u538b\u7f29\u7b56\u7565\u603b\u89c8<\/h4>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502                   \u4e0a\u4e0b\u6587\u538b\u7f29\u7b56\u7565\u51b3\u7b56\u6811                                  \u2502<br \/>\n\u2502                                                                     \u2502<br \/>\n\u2502                    \u5f53\u524d Token \u6570                                      \u2502<br \/>\n\u2502                        \u2502                                             \u2502<br \/>\n\u2502            \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                                 \u2502<br \/>\n\u2502            \u2502                       \u2502                                 \u2502<br \/>\n\u2502      &lt; 50% \u9884\u7b97              &gt; 50% \u9884\u7b97                               \u2502<br \/>\n\u2502            \u2502                       \u2502                                 \u2502<br \/>\n\u2502      \u4e0d\u538b\u7f29              \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                       \u2502<br \/>\n\u2502                          \u2502                   \u2502                       \u2502<br \/>\n\u2502                    &lt; 75% \u9884\u7b97           &gt; 75% \u9884\u7b97                     \u2502<br \/>\n\u2502                          \u2502                   \u2502                       \u2502<br \/>\n\u2502                    \u8f7b\u5ea6\u538b\u7f29              \u250c\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2510                  \u2502<br \/>\n\u2502                   (\u6d88\u606f\u88c1\u526a)            &lt; 90%    &gt; 90%                \u2502<br \/>\n\u2502                          \u2502              \u2502         \u2502                  \u2502<br \/>\n\u2502                          \u2502        \u4e2d\u5ea6\u538b\u7f29     \u91cd\u5ea6\u538b\u7f29                \u2502<br \/>\n\u2502                          \u2502       (\u6458\u8981&#043;\u88c1\u526a)  (\u5168\u91cf\u6458\u8981&#043;               \u2502<br \/>\n\u2502                          \u2502              \u2502     \u4ec5\u4fdd\u7559\u6700\u8fd13\u8f6e)           \u2502<br \/>\n\u2502                          v              v         v                  \u2502<br \/>\n\u2502                    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510              \u2502<br \/>\n\u2502                    \u2502     \u538b\u7f29\u540e Token &lt; 50% \u9884\u7b97       \u2502              \u2502<br \/>\n\u2502                    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518              \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<h4>2.3.2 \u6ed1\u52a8\u7a97\u53e3\u6458\u8981\u538b\u7f29\u7b97\u6cd5<\/h4>\n<p>\u8fd9\u662f Hermes Agent \u7684\u6838\u5fc3\u538b\u7f29\u7b97\u6cd5&#xff0c;\u91c7\u7528\u6ed1\u52a8\u7a97\u53e3 &#043; \u6e10\u8fdb\u5f0f\u6458\u8981\u7684\u65b9\u5f0f&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u4e0a\u4e0b\u6587\u538b\u7f29\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ContextCompressor<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u538b\u7f29\u9608\u503c&#xff08;\u5360\u9884\u7b97\u7684\u6bd4\u4f8b&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> compression_threshold<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">f64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4fdd\u7559\u6700\u8fd1\u6d88\u606f\u7684\u7a97\u53e3\u5927\u5c0f<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> recent_message_window<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6458\u8981\u6a21\u578b<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> summary_model<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ Token \u4f30\u7b97\u5668<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> token_estimator<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">TokenEstimator<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug, PartialEq)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">CompressionStrategy<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Light<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">Medium<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">Heavy<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">ContextCompressor<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6267\u884c\u4e0a\u4e0b\u6587\u538b\u7f29<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">compress<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        session<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">CompressionResult<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">CompressionError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> total_tokens <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>token_estimator<span class=\"token punctuation\">.<\/span><span class=\"token function\">estimate_session<\/span><span class=\"token punctuation\">(<\/span>session<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> budget <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>token_estimator<span class=\"token punctuation\">.<\/span><span class=\"token function\">get_budget<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>session<span class=\"token punctuation\">.<\/span>metadata<span class=\"token punctuation\">.<\/span>current_model<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>total_tokens <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">f64<\/span> <span class=\"token operator\">\/<\/span> budget <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">f64<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&lt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>compression_threshold <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CompressionResult<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">NoCompressionNeeded<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u6839\u636e\u538b\u7f29\u7ea7\u522b\u9009\u62e9\u7b56\u7565<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> ratio <span class=\"token operator\">&#061;<\/span> total_tokens <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">f64<\/span> <span class=\"token operator\">\/<\/span> budget <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">f64<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">if<\/span> ratio <span class=\"token operator\">&lt;<\/span> <span class=\"token number\">0.75<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">CompressionStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Light<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token keyword\">if<\/span> ratio <span class=\"token operator\">&lt;<\/span> <span class=\"token number\">0.90<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">CompressionStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Medium<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">CompressionStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Heavy<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">match<\/span> strategy <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">CompressionStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Light<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">light_compress<\/span><span class=\"token punctuation\">(<\/span>session<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">CompressionStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Medium<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">medium_compress<\/span><span class=\"token punctuation\">(<\/span>session<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">CompressionStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Heavy<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">heavy_compress<\/span><span class=\"token punctuation\">(<\/span>session<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">CompressionStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">None<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CompressionResult<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">NoCompressionNeeded<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u8f7b\u5ea6\u538b\u7f29&#xff1a;\u88c1\u526a\u5de5\u5177\u8c03\u7528\u7684\u8be6\u7ec6\u8f93\u51fa<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">light_compress<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        session<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">CompressionResult<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">CompressionError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> compressed_messages <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> tokens_saved <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0u64<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">for<\/span> msg <span class=\"token keyword\">in<\/span> <span class=\"token operator\">&amp;<\/span>session<span class=\"token punctuation\">.<\/span>messages <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> msg<span class=\"token punctuation\">.<\/span>role <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token class-name\">MessageRole<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Tool<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token comment\">\/\/ \u5c06\u5de5\u5177\u8c03\u7528\u7684\u8be6\u7ec6\u8f93\u51fa\u66ff\u6362\u4e3a\u6458\u8981<\/span><br \/>\n                <span class=\"token keyword\">let<\/span> summary <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">summarize_tool_output<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>msg<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                tokens_saved <span class=\"token operator\">&#043;&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>token_estimator<span class=\"token punctuation\">.<\/span><span class=\"token function\">estimate_message<\/span><span class=\"token punctuation\">(<\/span>msg<span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token operator\">&#8211;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>token_estimator<span class=\"token punctuation\">.<\/span><span class=\"token function\">estimate_text<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>summary<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>                compressed_messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Message<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    content<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">MessageContent<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Text<\/span><span class=\"token punctuation\">(<\/span>summary<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    metadata<span class=\"token punctuation\">:<\/span> msg<span class=\"token punctuation\">.<\/span>metadata<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token punctuation\">..<\/span>msg<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                compressed_messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span>msg<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CompressionResult<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Compressed<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            strategy<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">CompressionStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Light<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            messages<span class=\"token punctuation\">:<\/span> compressed_messages<span class=\"token punctuation\">,<\/span><br \/>\n            tokens_saved<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u4e2d\u5ea6\u538b\u7f29&#xff1a;\u5386\u53f2\u6d88\u606f\u6458\u8981 &#043; \u4fdd\u7559\u6700\u8fd1N\u8f6e<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">medium_compress<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        session<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">CompressionResult<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">CompressionError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> split_point <span class=\"token operator\">&#061;<\/span> session<span class=\"token punctuation\">.<\/span>messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">saturating_sub<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>recent_message_window<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u5c06\u65e9\u671f\u6d88\u606f\u751f\u6210\u6458\u8981<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> old_messages <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>session<span class=\"token punctuation\">.<\/span>messages<span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">..<\/span>split_point<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> recent_messages <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>session<span class=\"token punctuation\">.<\/span>messages<span class=\"token punctuation\">[<\/span>split_point<span class=\"token punctuation\">..<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> summary <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">generate_summary<\/span><span class=\"token punctuation\">(<\/span>old_messages<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> compressed <span class=\"token operator\">&#061;<\/span> <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token class-name\">Message<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">system<\/span><span class=\"token punctuation\">(<\/span>summary<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        compressed<span class=\"token punctuation\">.<\/span><span class=\"token function\">extend_from_slice<\/span><span class=\"token punctuation\">(<\/span>recent_messages<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> tokens_saved <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>token_estimator<span class=\"token punctuation\">.<\/span><span class=\"token function\">estimate_messages<\/span><span class=\"token punctuation\">(<\/span>old_messages<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token operator\">&#8211;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>token_estimator<span class=\"token punctuation\">.<\/span><span class=\"token function\">estimate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>compressed<span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CompressionResult<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Compressed<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            strategy<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">CompressionStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Medium<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            messages<span class=\"token punctuation\">:<\/span> compressed<span class=\"token punctuation\">,<\/span><br \/>\n            tokens_saved<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u91cd\u5ea6\u538b\u7f29&#xff1a;\u5168\u91cf\u6458\u8981 &#043; \u4ec5\u4fdd\u7559\u6700\u8fd13\u8f6e<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">heavy_compress<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        session<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">CompressionResult<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">CompressionError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u4fdd\u7559\u6700\u8fd13\u8f6e\u5bf9\u8bdd&#xff08;6\u6761\u6d88\u606f&#xff1a;3 user &#043; 3 assistant&#xff09;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> retain <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">6<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">min<\/span><span class=\"token punctuation\">(<\/span>session<span class=\"token punctuation\">.<\/span>messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> split_point <span class=\"token operator\">&#061;<\/span> session<span class=\"token punctuation\">.<\/span>messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#8211;<\/span> retain<span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> old_messages <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>session<span class=\"token punctuation\">.<\/span>messages<span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">..<\/span>split_point<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> recent_messages <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>session<span class=\"token punctuation\">.<\/span>messages<span class=\"token punctuation\">[<\/span>split_point<span class=\"token punctuation\">..<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u5982\u679c\u5df2\u6709\u4e4b\u524d\u7684\u6458\u8981&#xff0c;\u5c06\u65e7\u6458\u8981 &#043; \u65b0\u6d88\u606f\u4e00\u8d77\u538b\u7f29<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> summary_input <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>prev_summary<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>session<span class=\"token punctuation\">.<\/span>compressed_summary <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">merge_summary<\/span><span class=\"token punctuation\">(<\/span>prev_summary<span class=\"token punctuation\">,<\/span> old_messages<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">generate_detailed_summary<\/span><span class=\"token punctuation\">(<\/span>old_messages<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> compressed <span class=\"token operator\">&#061;<\/span> <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token class-name\">Message<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">system<\/span><span class=\"token punctuation\">(<\/span>summary_input<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        compressed<span class=\"token punctuation\">.<\/span><span class=\"token function\">extend_from_slice<\/span><span class=\"token punctuation\">(<\/span>recent_messages<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CompressionResult<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Compressed<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            strategy<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">CompressionStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Heavy<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            messages<span class=\"token punctuation\">:<\/span> compressed<span class=\"token punctuation\">,<\/span><br \/>\n            tokens_saved<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>token_estimator<span class=\"token punctuation\">.<\/span><span class=\"token function\">estimate_session<\/span><span class=\"token punctuation\">(<\/span>session<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token operator\">&#8211;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>token_estimator<span class=\"token punctuation\">.<\/span><span class=\"token function\">estimate_messages<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>compressed<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u4f7f\u7528 LLM \u751f\u6210\u5bf9\u8bdd\u6458\u8981<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">generate_summary<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        messages<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token punctuation\">[<\/span><span class=\"token class-name\">Message<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">CompressionError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> prompt <span class=\"token operator\">&#061;<\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token string\">r#&#034;\u8bf7\u5c06\u4ee5\u4e0b\u5bf9\u8bdd\u5386\u53f2\u538b\u7f29\u4e3a\u7b80\u6d01\u7684\u6458\u8981&#xff0c;\u4fdd\u7559&#xff1a;<br \/>\n1. \u7528\u6237\u7684\u6838\u5fc3\u9700\u6c42\u548c\u76ee\u6807<br \/>\n2. \u5df2\u7ecf\u505a\u51fa\u7684\u5173\u952e\u51b3\u7b56<br \/>\n3. \u91cd\u8981\u7684\u4e0a\u4e0b\u6587\u4fe1\u606f&#xff08;\u4eba\u540d\u3001\u6280\u672f\u6808\u3001\u7ea6\u675f\u6761\u4ef6\u7b49&#xff09;<br \/>\n4. \u672a\u89e3\u51b3\u7684\u95ee\u9898\u548c\u5f85\u529e\u4e8b\u9879<\/p>\n<p>\u5bf9\u8bdd\u5386\u53f2&#xff1a;<br \/>\n{}<\/p>\n<p>\u6458\u8981&#xff1a;&#034;#<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>m<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;[{}]: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> m<span class=\"token punctuation\">.<\/span>role<span class=\"token punctuation\">,<\/span><br \/>\n                    m<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_text<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or_default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">::<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span>_<span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">join<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\\\\n&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> summary <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">llm_call<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>summary_model<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span>prompt<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;[\u5bf9\u8bdd\u5386\u53f2\u6458\u8981]\\\\n{}&#034;<\/span><span class=\"token punctuation\">,<\/span> summary<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u5408\u5e76\u5df2\u6709\u6458\u8981\u4e0e\u65b0\u6d88\u606f&#xff08;\u589e\u91cf\u6458\u8981&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">merge_summary<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        prev_summary<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">Summary<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        new_messages<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token punctuation\">[<\/span><span class=\"token class-name\">Message<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">CompressionError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> prompt <span class=\"token operator\">&#061;<\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token string\">r#&#034;\u4ee5\u4e0b\u662f\u4e4b\u524d\u7684\u5bf9\u8bdd\u6458\u8981\u548c\u65b0\u589e\u7684\u5bf9\u8bdd\u5185\u5bb9&#xff0c;\u8bf7\u5408\u5e76\u4e3a\u4e00\u4e2a\u66f4\u65b0\u7684\u6458\u8981&#xff1a;<\/p>\n<p>\u3010\u5df2\u6709\u6458\u8981\u3011<br \/>\n{}<\/p>\n<p>\u3010\u65b0\u589e\u5bf9\u8bdd\u3011<br \/>\n{}<\/p>\n<p>\u3010\u66f4\u65b0\u540e\u7684\u6458\u8981\u3011&#034;#<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            prev_summary<span class=\"token punctuation\">.<\/span>text<span class=\"token punctuation\">,<\/span><br \/>\n            new_messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>m<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;[{}]: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> m<span class=\"token punctuation\">.<\/span>role<span class=\"token punctuation\">,<\/span><br \/>\n                    m<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_text<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or_default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">::<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span>_<span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">join<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\\\\n&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> merged <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">llm_call<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>summary_model<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span>prompt<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;[\u5bf9\u8bdd\u5386\u53f2\u6458\u8981&#xff08;\u66f4\u65b0&#xff09;]\\\\n{}&#034;<\/span><span class=\"token punctuation\">,<\/span> merged<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>2.3.3 \u538b\u7f29\u6548\u679c\u8bc4\u4f30<\/h4>\n<p>\u4ee5\u4e0b\u662f\u4e0d\u540c\u538b\u7f29\u7b56\u7565\u5728\u5b9e\u6d4b\u4e2d\u7684\u6548\u679c\u5bf9\u6bd4&#xff1a;<\/p>\n<table>\n<tr>\u538b\u7f29\u7b56\u7565\u89e6\u53d1\u6761\u4ef6Token \u538b\u7f29\u7387\u4fe1\u606f\u4fdd\u7559\u7387\u538b\u7f29\u5ef6\u8fdf\u9002\u7528\u573a\u666f<\/tr>\n<tbody>\n<tr>\n<td>\u8f7b\u5ea6\u538b\u7f29<\/td>\n<td>50%-75% \u9884\u7b97<\/td>\n<td>15%-25%<\/td>\n<td>95%&#043;<\/td>\n<td>&lt;100ms<\/td>\n<td>\u5de5\u5177\u8c03\u7528\u8f83\u591a\u7684\u573a\u666f<\/td>\n<\/tr>\n<tr>\n<td>\u4e2d\u5ea6\u538b\u7f29<\/td>\n<td>75%-90% \u9884\u7b97<\/td>\n<td>40%-60%<\/td>\n<td>85%-90%<\/td>\n<td>500ms-2s<\/td>\n<td>\u957f\u5bf9\u8bdd&#xff08;&gt;20\u8f6e&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>\u91cd\u5ea6\u538b\u7f29<\/td>\n<td>&gt;90% \u9884\u7b97<\/td>\n<td>70%-85%<\/td>\n<td>70%-80%<\/td>\n<td>1s-3s<\/td>\n<td>\u8d85\u957f\u5bf9\u8bdd&#xff08;&gt;50\u8f6e&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>\u4e0d\u538b\u7f29<\/td>\n<td>&lt;50% \u9884\u7b97<\/td>\n<td>0%<\/td>\n<td>100%<\/td>\n<td>0ms<\/td>\n<td>\u77ed\u5bf9\u8bdd&#xff08;&lt;10\u8f6e&#xff09;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u4fe1\u606f\u4fdd\u7559\u7387\u7684\u8861\u91cf\u65b9\u5f0f&#xff1a;\u538b\u7f29\u524d\u540e&#xff0c;\u4f7f\u7528\u540c\u4e00\u7ec4\u6d4b\u8bd5\u95ee\u9898\u8bc4\u4f30 Agent \u56de\u7b54\u7684\u51c6\u786e\u7387&#xff0c;\u4ee5\u672a\u538b\u7f29\u7248\u672c\u7684\u51c6\u786e\u7387\u4e3a\u57fa\u51c6\u8ba1\u7b97\u4fdd\u7559\u7387\u3002<\/p>\n<h4>2.3.4 \u538b\u7f29\u7b56\u7565\u7684\u9009\u62e9\u8003\u91cf<\/h4>\n<p>\u538b\u7f29\u7b56\u7565\u7684\u9009\u62e9\u5e76\u975e\u7b80\u5355\u7684\u9608\u503c\u89e6\u53d1&#xff0c;\u8fd8\u9700\u8981\u7efc\u5408\u8003\u8651\u4ee5\u4e0b\u56e0\u7d20&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u538b\u7f29\u51b3\u7b56\u4e0a\u4e0b\u6587<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">CompressionDecisionContext<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5f53\u524d Token \u4f7f\u7528\u91cf<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> current_tokens<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6a21\u578b\u4e0a\u4e0b\u6587\u7a97\u53e3\u5927\u5c0f<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> context_window<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5bf9\u8bdd\u8f6e\u6b21<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> turn_count<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u32<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5de5\u5177\u8c03\u7528\u5bc6\u5ea6&#xff08;\u6700\u8fd110\u8f6e\u4e2d\u5de5\u5177\u8c03\u7528\u7684\u6bd4\u4f8b&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> tool_call_density<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">f64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7528\u6237\u60c5\u7eea\u6307\u6807&#xff08;\u57fa\u4e8e\u6700\u8fd1\u6d88\u606f\u7684\u8bed\u4e49\u5206\u6790&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> user_sentiment<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Sentiment<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4f1a\u8bdd\u91cd\u8981\u6027\u8bc4\u5206<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> session_importance<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">f64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u53ef\u7528\u538b\u7f29\u9884\u7b97&#xff08;\u65f6\u95f4&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> time_budget<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u667a\u80fd\u538b\u7f29\u7b56\u7565\u9009\u62e9\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">select_strategy<\/span><span class=\"token punctuation\">(<\/span>ctx<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">CompressionDecisionContext<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">CompressionStrategy<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">let<\/span> ratio <span class=\"token operator\">&#061;<\/span> ctx<span class=\"token punctuation\">.<\/span>current_tokens <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">f64<\/span> <span class=\"token operator\">\/<\/span> ctx<span class=\"token punctuation\">.<\/span>context_window <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">f64<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u5982\u679c\u65f6\u95f4\u9884\u7b97\u7d27\u5f20&#xff0c;\u9009\u62e9\u6700\u5feb\u7684\u7b56\u7565<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> ctx<span class=\"token punctuation\">.<\/span>time_budget <span class=\"token operator\">&lt;<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">from_millis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">200<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">if<\/span> ratio <span class=\"token operator\">&gt;<\/span> <span class=\"token number\">0.9<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">CompressionStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Medium<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">CompressionStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Light<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u5982\u679c\u7528\u6237\u60c5\u7eea\u6d88\u6781&#xff08;\u4e0d\u8010\u70e6&#xff09;&#xff0c;\u51cf\u5c11\u538b\u7f29\u5ef6\u8fdf<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> ctx<span class=\"token punctuation\">.<\/span>user_sentiment <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token class-name\">Sentiment<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Negative<\/span> <span class=\"token operator\">&amp;&amp;<\/span> ratio <span class=\"token operator\">&lt;<\/span> <span class=\"token number\">0.9<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">CompressionStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Light<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u9ad8\u91cd\u8981\u6027\u4f1a\u8bdd&#xff0c;\u4f7f\u7528\u66f4\u4fdd\u5b88\u7684\u538b\u7f29<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> ctx<span class=\"token punctuation\">.<\/span>session_importance <span class=\"token operator\">&gt;<\/span> <span class=\"token number\">0.8<\/span> <span class=\"token operator\">&amp;&amp;<\/span> ratio <span class=\"token operator\">&lt;<\/span> <span class=\"token number\">0.85<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">CompressionStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Light<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u6807\u51c6\u51b3\u7b56\u8def\u5f84<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> ratio <span class=\"token operator\">&lt;<\/span> <span class=\"token number\">0.5<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">CompressionStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">None<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token keyword\">if<\/span> ratio <span class=\"token operator\">&lt;<\/span> <span class=\"token number\">0.75<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">CompressionStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Light<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token keyword\">if<\/span> ratio <span class=\"token operator\">&lt;<\/span> <span class=\"token number\">0.90<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">CompressionStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Medium<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">CompressionStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Heavy<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h3>2.4 \u5e76\u884c\u4f1a\u8bdd\u9694\u79bb\u65b9\u6848<\/h3>\n<h4>2.4.1 \u9694\u79bb\u67b6\u6784<\/h4>\n<p>Hermes Agent \u652f\u6301\u540c\u4e00\u7528\u6237\u540c\u65f6\u6301\u6709\u591a\u4e2a\u6d3b\u8dc3\u4f1a\u8bdd&#xff0c;\u6bcf\u4e2a\u4f1a\u8bdd\u62e5\u6709\u72ec\u7acb\u7684\u4e0a\u4e0b\u6587\u7a7a\u95f4&#xff0c;\u4e92\u4e0d\u5e72\u6270&#xff1a;<\/p>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502                    \u5e76\u884c\u4f1a\u8bdd\u9694\u79bb\u67b6\u6784                                     \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502                    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                                   \u2502<br \/>\n\u2502                    \u2502   User A     \u2502                                   \u2502<br \/>\n\u2502                    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                                   \u2502<br \/>\n\u2502                           \u2502                                           \u2502<br \/>\n\u2502              \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                              \u2502<br \/>\n\u2502              \u2502            \u2502            \u2502                              \u2502<br \/>\n\u2502         Session #1   Session #2   Session #3                          \u2502<br \/>\n\u2502         (\u98de\u4e66\u6e20\u9053)   (Web\u6e20\u9053)   (API\u6e20\u9053)                              \u2502<br \/>\n\u2502              \u2502            \u2502            \u2502                              \u2502<br \/>\n\u2502     \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2510  \u250c\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2510  \u250c\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                     \u2502<br \/>\n\u2502     \u2502 Context    \u2502  \u2502 Context  \u2502  \u2502 Context    \u2502                     \u2502<br \/>\n\u2502     \u2502 \u00b7 messages \u2502  \u2502 \u00b7 messages\u2502 \u2502 \u00b7 messages \u2502                     \u2502<br \/>\n\u2502     \u2502 \u00b7 tools    \u2502  \u2502 \u00b7 tools  \u2502  \u2502 \u00b7 tools    \u2502                     \u2502<br \/>\n\u2502     \u2502 \u00b7 metadata \u2502  \u2502 \u00b7 metadata\u2502 \u2502 \u00b7 metadata \u2502                     \u2502<br \/>\n\u2502     \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                     \u2502<br \/>\n\u2502              \u2502            \u2502            \u2502                              \u2502<br \/>\n\u2502              \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                              \u2502<br \/>\n\u2502                           \u2502                                           \u2502<br \/>\n\u2502                    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                                   \u2502<br \/>\n\u2502                    \u2502 \u5171\u4eab\u8bb0\u5fc6\u5c42     \u2502                                   \u2502<br \/>\n\u2502                    \u2502 (User Level) \u2502                                   \u2502<br \/>\n\u2502                    \u2502 \u00b7 \u7528\u6237\u753b\u50cf    \u2502                                   \u2502<br \/>\n\u2502                    \u2502 \u00b7 \u957f\u671f\u8bb0\u5fc6    \u2502                                   \u2502<br \/>\n\u2502                    \u2502 \u00b7 \u504f\u597d\u8bbe\u7f6e    \u2502                                   \u2502<br \/>\n\u2502                    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                                   \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<p>\u4f1a\u8bdd\u9694\u79bb\u7684\u6838\u5fc3\u8bbe\u8ba1\u539f\u5219&#xff1a;<\/p>\n<ul>\n<li>\u4e0a\u4e0b\u6587\u9694\u79bb&#xff1a;\u6bcf\u4e2a\u4f1a\u8bdd\u62e5\u6709\u72ec\u7acb\u7684\u6d88\u606f\u5e8f\u5217\u3001\u5de5\u5177\u8c03\u7528\u6808\u548c\u5143\u6570\u636e&#xff0c;\u4e00\u4e2a\u4f1a\u8bdd\u7684\u4e0a\u4e0b\u6587\u53d8\u66f4\u4e0d\u4f1a\u5f71\u54cd\u5176\u4ed6\u4f1a\u8bdd<\/li>\n<li>\u8bb0\u5fc6\u5171\u4eab&#xff1a;\u7528\u6237\u7ea7\u957f\u671f\u8bb0\u5fc6&#xff08;\u7528\u6237\u753b\u50cf\u3001\u504f\u597d\u8bbe\u7f6e\u3001\u5386\u53f2\u51b3\u7b56&#xff09;\u5728\u6240\u6709\u4f1a\u8bdd\u95f4\u5171\u4eab&#xff0c;\u4f46\u901a\u8fc7\u53ea\u8bfb\u5feb\u7167\u65b9\u5f0f\u8bbf\u95ee&#xff0c;\u907f\u514d\u5e76\u53d1\u5199\u5165\u51b2\u7a81<\/li>\n<li>\u8d44\u6e90\u9694\u79bb&#xff1a;\u6bcf\u4e2a\u4f1a\u8bdd\u6709\u72ec\u7acb\u7684 Token \u914d\u989d\u3001\u5de5\u5177\u8c03\u7528\u914d\u989d\u548c\u901f\u7387\u9650\u5236&#xff0c;\u9632\u6b62\u5355\u4e2a\u4f1a\u8bdd\u8017\u5c3d\u7528\u6237\u8d44\u6e90<\/li>\n<li>\u663e\u5f0f\u5171\u4eab&#xff1a;\u4f1a\u8bdd\u95f4\u7684\u4fe1\u606f\u5171\u4eab\u662f\u663e\u5f0f\u64cd\u4f5c\u800c\u975e\u81ea\u52a8\u884c\u4e3a&#xff0c;\u7528\u6237\u6216\u7cfb\u7edf\u5fc5\u987b\u660e\u786e\u6307\u5b9a\u8981\u5171\u4eab\u7684\u6d88\u606f\u548c\u4e0a\u4e0b\u6587<\/li>\n<\/ul>\n<h4>2.4.2 \u9694\u79bb\u5b9e\u73b0<\/h4>\n<p><span class=\"token comment\">\/\/\/ \u4f1a\u8bdd\u9694\u79bb\u7ba1\u7406\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">SessionIsolationManager<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7528\u6237\u4f1a\u8bdd\u6620\u5c04&#xff1a;UserId -&gt; Set&lt;SessionId&gt;<\/span><br \/>\n    user_sessions<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">UserId<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">HashSet<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4f1a\u8bdd\u4e0a\u4e0b\u6587\u5b58\u50a8&#xff08;\u6309 SessionId \u9694\u79bb&#xff09;<\/span><br \/>\n    session_contexts<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SessionStore<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7528\u6237\u7ea7\u5171\u4eab\u8bb0\u5fc6<\/span><br \/>\n    user_memory<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">UserMemoryStore<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6bcf\u7528\u6237\u6700\u5927\u5e76\u53d1\u4f1a\u8bdd\u6570<\/span><br \/>\n    max_sessions_per_user<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">SessionIsolationManager<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u521b\u5efa\u65b0\u4f1a\u8bdd&#xff08;\u68c0\u67e5\u5e76\u53d1\u9650\u5236&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">create_session<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        user_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">UserId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        channel<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">IsolationError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> user_sessions <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>user_sessions<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> active_count <span class=\"token operator\">&#061;<\/span> user_sessions<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>user_id<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>s<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> s<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> active_count <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>max_sessions_per_user <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Err<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">IsolationError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">MaxSessionsExceeded<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                user_id<span class=\"token punctuation\">:<\/span> user_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                current<span class=\"token punctuation\">:<\/span> active_count<span class=\"token punctuation\">,<\/span><br \/>\n                max<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>max_sessions_per_user<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> session_id <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get_machine_id<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            channel<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_u16<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u521b\u5efa\u9694\u79bb\u7684\u4e0a\u4e0b\u6587\u7a7a\u95f4<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> context <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            session_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            user_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            channel<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>session_contexts<span class=\"token punctuation\">.<\/span><span class=\"token function\">put<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>session_id<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span>context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        user_sessions<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">entry<\/span><span class=\"token punctuation\">(<\/span>user_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">or_insert_with<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">HashSet<\/span><span class=\"token punctuation\">::<\/span>new<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">insert<\/span><span class=\"token punctuation\">(<\/span>session_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>session_id<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u83b7\u53d6\u4f1a\u8bdd\u4e0a\u4e0b\u6587&#xff08;\u786e\u4fdd\u9694\u79bb\u6027&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">get_context<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        session_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">IsolationError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u76f4\u63a5\u4ece\u9694\u79bb\u5b58\u50a8\u83b7\u53d6&#xff0c;\u4e0d\u7ecf\u8fc7\u7528\u6237\u7ea7\u8def\u7531<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>session_contexts<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>session_id<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">ok_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">IsolationError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">SessionNotFound<\/span><span class=\"token punctuation\">(<\/span>session_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u83b7\u53d6\u7528\u6237\u7ea7\u5171\u4eab\u8bb0\u5fc6&#xff08;\u6240\u6709\u4f1a\u8bdd\u53ef\u8bfb&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">get_user_memory<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        user_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">UserId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">UserMemory<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">IsolationError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>user_memory<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>user_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u4f1a\u8bdd\u95f4\u4fe1\u606f\u5171\u4eab&#xff08;\u663e\u5f0f\u64cd\u4f5c&#xff0c;\u975e\u81ea\u52a8&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">share_context<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        from_session<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        to_session<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        message_ids<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token punctuation\">[<\/span><span class=\"token class-name\">MessageId<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">IsolationError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u9a8c\u8bc1\u4e24\u4e2a\u4f1a\u8bdd\u5c5e\u4e8e\u540c\u4e00\u7528\u6237<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> from_ctx <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>session_contexts<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>from_session<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> to_ctx <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>session_contexts<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>to_session<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> from_ctx<span class=\"token punctuation\">.<\/span>user_id <span class=\"token operator\">!&#061;<\/span> to_ctx<span class=\"token punctuation\">.<\/span>user_id <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Err<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">IsolationError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">CrossUserSharing<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                from_user<span class=\"token punctuation\">:<\/span> from_ctx<span class=\"token punctuation\">.<\/span>user_id<span class=\"token punctuation\">,<\/span><br \/>\n                to_user<span class=\"token punctuation\">:<\/span> to_ctx<span class=\"token punctuation\">.<\/span>user_id<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u4ec5\u590d\u5236\u6307\u5b9a\u6d88\u606f\u5230\u76ee\u6807\u4f1a\u8bdd<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> messages_to_share<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Message<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&#061;<\/span> from_ctx<span class=\"token punctuation\">.<\/span>messages<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">filter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>m<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> message_ids<span class=\"token punctuation\">.<\/span><span class=\"token function\">contains<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>m<span class=\"token punctuation\">.<\/span>message_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">cloned<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> to_ctx <span class=\"token operator\">&#061;<\/span> to_ctx<span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> msg <span class=\"token keyword\">in<\/span> messages_to_share <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token comment\">\/\/ \u6dfb\u52a0\u6765\u6e90\u6807\u8bb0<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> shared_msg <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Message<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                metadata<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">MessageMetadata<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    shared_from<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>from_session<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token punctuation\">..<\/span>msg<span class=\"token punctuation\">.<\/span>metadata<br \/>\n                <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token punctuation\">..<\/span>msg<br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            to_ctx<span class=\"token punctuation\">.<\/span>messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span>shared_msg<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>session_contexts<span class=\"token punctuation\">.<\/span><span class=\"token function\">put<\/span><span class=\"token punctuation\">(<\/span>to_session<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span>to_ctx<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>2.4.3 \u8d44\u6e90\u914d\u989d\u7ba1\u7406<\/h4>\n<p>\u4e3a\u9632\u6b62\u5355\u4e2a\u7528\u6237\u6216\u4f1a\u8bdd\u6d88\u8017\u8fc7\u591a\u8d44\u6e90&#xff0c;Gateway \u5b9e\u73b0\u4e86\u591a\u7ef4\u5ea6\u8d44\u6e90\u914d\u989d\u7ba1\u7406&#xff1a;<\/p>\n<p><span class=\"token comment\"># \u8d44\u6e90\u914d\u989d\u914d\u7f6e\u793a\u4f8b<\/span><br \/>\n<span class=\"token key atrule\">quota<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token key atrule\">per_user<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">max_active_sessions<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">5<\/span><br \/>\n    <span class=\"token key atrule\">max_requests_per_minute<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">120<\/span><br \/>\n    <span class=\"token key atrule\">max_tokens_per_hour<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">500000<\/span><br \/>\n    <span class=\"token key atrule\">max_tool_calls_per_day<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1000<\/span><\/p>\n<p>  <span class=\"token key atrule\">per_session<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">max_messages<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">500<\/span><br \/>\n    <span class=\"token key atrule\">max_tokens<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">100000<\/span><br \/>\n    <span class=\"token key atrule\">max_tool_calls<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">50<\/span><br \/>\n    <span class=\"token key atrule\">max_duration<\/span><span class=\"token punctuation\">:<\/span> 24h<\/p>\n<p>  <span class=\"token key atrule\">per_channel<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">web<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">max_concurrent_sessions_per_user<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">3<\/span><br \/>\n    <span class=\"token key atrule\">feishu<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">max_concurrent_sessions_per_user<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">2<\/span><br \/>\n    <span class=\"token key atrule\">api<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">max_concurrent_sessions_per_user<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">10<\/span><br \/>\n      <span class=\"token key atrule\">max_rps<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">50<\/span><\/p>\n<p>  <span class=\"token key atrule\">enforcement<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">strategy<\/span><span class=\"token punctuation\">:<\/span> reject  <span class=\"token comment\"># reject | queue | degrade<\/span><br \/>\n    <span class=\"token key atrule\">queue_timeout<\/span><span class=\"token punctuation\">:<\/span> 30s<br \/>\n    <span class=\"token key atrule\">degrade_message<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;\u5f53\u524d\u8bf7\u6c42\u91cf\u8f83\u5927&#xff0c;\u5df2\u5207\u6362\u5230\u7b80\u5316\u6a21\u5f0f&#034;<\/span><\/p>\n<p>\u914d\u989d\u7ba1\u7406\u7684\u6267\u884c\u7b56\u7565\u6709\u4e09\u79cd\u6a21\u5f0f&#xff1a;<\/p>\n<ul>\n<li>reject&#xff08;\u62d2\u7edd&#xff09;&#xff1a;\u8d85\u51fa\u914d\u989d\u7684\u8bf7\u6c42\u76f4\u63a5\u8fd4\u56de 429 \u9519\u8bef&#xff0c;\u5ba2\u6237\u7aef\u9700\u8981\u81ea\u884c\u5904\u7406\u91cd\u8bd5<\/li>\n<li>queue&#xff08;\u6392\u961f&#xff09;&#xff1a;\u8d85\u51fa\u914d\u989d\u7684\u8bf7\u6c42\u8fdb\u5165\u7b49\u5f85\u961f\u5217&#xff0c;\u5728\u8d85\u65f6\u65f6\u95f4\u5185\u6709\u914d\u989d\u91ca\u653e\u5219\u7ee7\u7eed\u5904\u7406<\/li>\n<li>degrade&#xff08;\u964d\u7ea7&#xff09;&#xff1a;\u8d85\u51fa\u914d\u989d\u540e\u81ea\u52a8\u964d\u7ea7\u670d\u52a1\u2014\u2014\u4f7f\u7528\u66f4\u5c0f\u7684\u6a21\u578b\u3001\u51cf\u5c11\u5de5\u5177\u8c03\u7528\u3001\u8df3\u8fc7\u8bb0\u5fc6\u68c0\u7d22\u7b49<\/li>\n<\/ul>\n<h3>2.5 \u4f1a\u8bdd\u751f\u547d\u5468\u671f\u7ba1\u7406<\/h3>\n<h4>2.5.1 \u751f\u547d\u5468\u671f\u72b6\u6001\u673a<\/h4>\n<p>                    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n         \u521b\u5efa \u2500\u2500\u2500\u2500&gt; \u2502  Active   \u2502 &lt;\u2500\u2500\u2500\u2500 \u6062\u590d<br \/>\n                    \u2514\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n                          \u2502<br \/>\n              \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n              \u2502           \u2502           \u2502<br \/>\n              v           v           v<br \/>\n        \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n        \u2502  Idle    \u2502 \u2502 Paused   \u2502 \u2502 Migrating\u2502<br \/>\n        \u2502 (\u8d85\u65f6\u7b49\u5f85) \u2502 \u2502 (\u7528\u6237\u6682\u505c) \u2502 \u2502 (\u8282\u70b9\u8fc1\u79fb) \u2502<br \/>\n        \u2514\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n             \u2502            \u2502            \u2502<br \/>\n             \u2502   \u6062\u590d &lt;\u2500\u2500\u2500\u2518    \u5b8c\u6210 \u2500\u2500\u2500\u2518<br \/>\n             \u2502            \u2502            \u2502<br \/>\n             v            v            v<br \/>\n        \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n        \u2502 Expiring \u2502 \u2502  Active  \u2502 \u2502  Active  \u2502<br \/>\n        \u2502 (\u5373\u5c06\u8fc7\u671f) \u2502 \u2502          \u2502 \u2502          \u2502<br \/>\n        \u2514\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n              \u2502<br \/>\n              v<br \/>\n        \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n        \u2502 Archived \u2502<br \/>\n        \u2502 (\u5df2\u5f52\u6863)  \u2502<br \/>\n        \u2514\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2518<br \/>\n              \u2502<br \/>\n              v<br \/>\n        \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n        \u2502 Deleted  \u2502<br \/>\n        \u2502 (\u5df2\u5220\u9664)  \u2502<br \/>\n        \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<p><span class=\"token comment\">\/\/\/ \u4f1a\u8bdd\u751f\u547d\u5468\u671f\u72b6\u6001<\/span><br \/>\n<span class=\"token attribute attr-name\">#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">SessionStatus<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6d3b\u8dc3\u72b6\u6001&#xff0c;\u6b63\u5728\u5904\u7406\u8bf7\u6c42<\/span><br \/>\n    <span class=\"token class-name\">Active<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7a7a\u95f2\u72b6\u6001&#xff0c;\u7b49\u5f85\u7528\u6237\u8f93\u5165<\/span><br \/>\n    <span class=\"token class-name\">Idle<\/span> <span class=\"token punctuation\">{<\/span> idle_since<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">DateTime<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6682\u505c\u72b6\u6001&#xff0c;\u7528\u6237\u4e3b\u52a8\u6682\u505c<\/span><br \/>\n    <span class=\"token class-name\">Paused<\/span> <span class=\"token punctuation\">{<\/span> paused_at<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">DateTime<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u8fc1\u79fb\u4e2d\u72b6\u6001&#xff0c;\u6b63\u5728\u8de8\u8282\u70b9\u8fc1\u79fb<\/span><br \/>\n    <span class=\"token class-name\">Migrating<\/span> <span class=\"token punctuation\">{<\/span> from_node<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">NodeId<\/span><span class=\"token punctuation\">,<\/span> to_node<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">NodeId<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5373\u5c06\u8fc7\u671f<\/span><br \/>\n    <span class=\"token class-name\">Expiring<\/span> <span class=\"token punctuation\">{<\/span> expire_at<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">DateTime<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5df2\u5f52\u6863&#xff08;\u4ece\u70ed\u5b58\u50a8\u8f6c\u79fb\u5230\u51b7\u5b58\u50a8&#xff09;<\/span><br \/>\n    <span class=\"token class-name\">Archived<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5df2\u5220\u9664<\/span><br \/>\n    <span class=\"token class-name\">Deleted<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u4f1a\u8bdd\u751f\u547d\u5468\u671f\u7ba1\u7406\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">SessionLifecycleManager<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7a7a\u95f2\u8d85\u65f6&#xff08;\u81ea\u52a8\u8f6c\u4e3a Idle&#xff09;<\/span><br \/>\n    idle_timeout<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u8fc7\u671f\u65f6\u95f4&#xff08;Idle \u540e\u591a\u4e45\u8f6c\u4e3a Expiring&#xff09;<\/span><br \/>\n    expire_timeout<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5f52\u6863\u65f6\u95f4&#xff08;Expiring \u540e\u591a\u4e45\u8f6c\u4e3a Archived&#xff09;<\/span><br \/>\n    archive_timeout<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5220\u9664\u65f6\u95f4&#xff08;Archived \u540e\u591a\u4e45\u7269\u7406\u5220\u9664&#xff09;<\/span><br \/>\n    delete_timeout<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u70ed\u5b58\u50a8<\/span><br \/>\n    hot_store<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HotSessionStore<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u51b7\u5b58\u50a8<\/span><br \/>\n    cold_store<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ColdSessionStore<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">SessionLifecycleManager<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5b9a\u65f6\u626b\u63cf\u4f1a\u8bdd\u72b6\u6001&#xff0c;\u6267\u884c\u72b6\u6001\u8f6c\u6362<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">run_lifecycle_scan<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> interval <span class=\"token operator\">&#061;<\/span> <span class=\"token namespace\">tokio<span class=\"token punctuation\">::<\/span>time<span class=\"token punctuation\">::<\/span><\/span><span class=\"token function\">interval<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">from_secs<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">30<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">loop<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            interval<span class=\"token punctuation\">.<\/span><span class=\"token function\">tick<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ 1. \u626b\u63cf Active \u4f1a\u8bdd&#xff0c;\u68c0\u67e5\u662f\u5426\u7a7a\u95f2<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> idle_sessions <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>hot_store<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">find_sessions_idle_before<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#8211;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>idle_timeout<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">for<\/span> session_id <span class=\"token keyword\">in<\/span> idle_sessions <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">transition_to_idle<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>session_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ 2. \u626b\u63cf Idle \u4f1a\u8bdd&#xff0c;\u68c0\u67e5\u662f\u5426\u8fc7\u671f<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> expiring_sessions <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>hot_store<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">find_sessions_idle_before<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#8211;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>expire_timeout<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">for<\/span> session_id <span class=\"token keyword\">in<\/span> expiring_sessions <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">transition_to_expiring<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>session_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ 3. \u626b\u63cf Expiring \u4f1a\u8bdd&#xff0c;\u6267\u884c\u5f52\u6863<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> archive_sessions <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>hot_store<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">find_sessions_expiring_before<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">for<\/span> session_id <span class=\"token keyword\">in<\/span> archive_sessions <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">archive_session<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>session_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ 4. \u626b\u63cf Archived \u4f1a\u8bdd&#xff0c;\u6267\u884c\u7269\u7406\u5220\u9664<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> delete_sessions <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>cold_store<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">find_sessions_archived_before<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#8211;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>delete_timeout<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">for<\/span> session_id <span class=\"token keyword\">in<\/span> delete_sessions <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">delete_session<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>session_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u6062\u590d\u5df2\u5f52\u6863\u7684\u4f1a\u8bdd<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">restore_session<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        session_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">LifecycleError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ 1. \u4ece\u51b7\u5b58\u50a8\u8bfb\u53d6\u4f1a\u8bdd\u6570\u636e<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> session <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>cold_store<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>session_id<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">ok_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LifecycleError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">SessionNotFound<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 2. \u5199\u5165\u70ed\u5b58\u50a8<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>hot_store<span class=\"token punctuation\">.<\/span><span class=\"token function\">put<\/span><span class=\"token punctuation\">(<\/span>session_id<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span>session<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 3. \u66f4\u65b0\u72b6\u6001\u4e3a Active<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> session <span class=\"token operator\">&#061;<\/span> session<span class=\"token punctuation\">;<\/span><br \/>\n        session<span class=\"token punctuation\">.<\/span>status <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">SessionStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Active<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        session<span class=\"token punctuation\">.<\/span>last_active_at <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Utc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>session<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>2.5.2 \u51b7\u70ed\u5206\u79bb\u5b58\u50a8\u7b56\u7565<\/h4>\n<p>\u4f1a\u8bdd\u6570\u636e\u5728\u4e0d\u540c\u751f\u547d\u5468\u671f\u9636\u6bb5\u5b58\u50a8\u5728\u4e0d\u540c\u4ecb\u8d28\u4e2d&#xff0c;\u4ee5\u5e73\u8861\u8bbf\u95ee\u901f\u5ea6\u548c\u5b58\u50a8\u6210\u672c&#xff1a;<\/p>\n<table>\n<tr>\u5b58\u50a8\u5c42\u5b58\u50a8\u4ecb\u8d28\u8bbf\u95ee\u5ef6\u8fdf\u5b58\u50a8\u6210\u672c\u4fdd\u7559\u65f6\u957f\u9002\u7528\u72b6\u6001<\/tr>\n<tbody>\n<tr>\n<td>\u70ed\u5b58\u50a8<\/td>\n<td>Redis Cluster<\/td>\n<td>&lt;1ms<\/td>\n<td>\u9ad8<\/td>\n<td>\u5b9e\u65f6<\/td>\n<td>Active, Idle<\/td>\n<\/tr>\n<tr>\n<td>\u6e29\u5b58\u50a8<\/td>\n<td>PostgreSQL<\/td>\n<td>&lt;10ms<\/td>\n<td>\u4e2d<\/td>\n<td>7\u5929<\/td>\n<td>Expiring<\/td>\n<\/tr>\n<tr>\n<td>\u51b7\u5b58\u50a8<\/td>\n<td>S3 \u5bf9\u8c61\u5b58\u50a8<\/td>\n<td>&lt;500ms<\/td>\n<td>\u4f4e<\/td>\n<td>90\u5929<\/td>\n<td>Archived<\/td>\n<\/tr>\n<tr>\n<td>\u5220\u9664<\/td>\n<td>&#8211;<\/td>\n<td>&#8211;<\/td>\n<td>&#8211;<\/td>\n<td>&#8211;<\/td>\n<td>Deleted<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u51b7\u70ed\u5206\u79bb\u7684\u5173\u952e\u8bbe\u8ba1\u70b9&#xff1a;<\/p>\n<ul>\n<li>\u5f02\u6b65\u8fc1\u79fb&#xff1a;\u4f1a\u8bdd\u4ece\u70ed\u5b58\u50a8\u5230\u51b7\u5b58\u50a8\u7684\u8fc1\u79fb\u662f\u5f02\u6b65\u64cd\u4f5c&#xff0c;\u4e0d\u963b\u585e\u4e3b\u6d41\u7a0b<\/li>\n<li>\u900f\u660e\u6062\u590d&#xff1a;\u5f53\u7528\u6237\u6062\u590d\u5df2\u5f52\u6863\u4f1a\u8bdd\u65f6&#xff0c;Gateway \u81ea\u52a8\u4ece\u51b7\u5b58\u50a8\u52a0\u8f7d\u6570\u636e\u5230\u70ed\u5b58\u50a8&#xff0c;\u5bf9\u7528\u6237\u900f\u660e<\/li>\n<li>\u9884\u52a0\u8f7d&#xff1a;\u7cfb\u7edf\u53ef\u4ee5\u57fa\u4e8e\u7528\u6237\u884c\u4e3a\u9884\u6d4b&#xff0c;\u63d0\u524d\u5c06\u53ef\u80fd\u6062\u590d\u7684\u5f52\u6863\u4f1a\u8bdd\u9884\u52a0\u8f7d\u5230\u70ed\u5b58\u50a8<\/li>\n<li>\u6e10\u8fdb\u5f0f\u5220\u9664&#xff1a;\u5220\u9664\u64cd\u4f5c\u5148\u6807\u8bb0\u4e3a\u8f6f\u5220\u9664&#xff0c;\u4fdd\u7559 24 \u5c0f\u65f6\u7684\u6062\u590d\u7a97\u53e3\u540e\u624d\u6267\u884c\u7269\u7406\u5220\u9664<\/li>\n<\/ul>\n<hr \/>\n<h2>\u7b2c\u4e09\u7ae0 \u6e20\u9053\u9002\u914d\u5668\u67b6\u6784<\/h2>\n<p>\u6e20\u9053\u9002\u914d\u5668\u662f Gateway \u4e0e\u5916\u90e8\u4e16\u754c\u6c9f\u901a\u7684\u6865\u6881\u3002\u5b83\u5c06\u5404\u5e73\u53f0\u5343\u5dee\u4e07\u522b\u7684\u6d88\u606f\u534f\u8bae\u7edf\u4e00\u7ffb\u8bd1\u4e3a Gateway \u5185\u90e8\u6807\u51c6\u683c\u5f0f&#xff0c;\u4f7f\u5f97\u6838\u5fc3\u5904\u7406\u903b\u8f91\u5b8c\u5168\u65e0\u9700\u611f\u77e5\u6e20\u9053\u5dee\u5f02\u3002\u8fd9\u4e00\u5c42\u7684\u8bbe\u8ba1\u8d28\u91cf\u76f4\u63a5\u51b3\u5b9a\u4e86\u7cfb\u7edf\u7684\u53ef\u6269\u5c55\u6027\u548c\u591a\u6e20\u9053\u63a5\u5165\u6548\u7387\u3002<\/p>\n<h3>3.1 \u9002\u914d\u5668\u6a21\u5f0f\u8bbe\u8ba1<\/h3>\n<h4>3.1.1 \u6838\u5fc3\u63a5\u53e3\u5b9a\u4e49<\/h4>\n<p>Hermes Agent \u5b9a\u4e49\u4e86\u4e00\u5957\u7edf\u4e00\u7684\u6e20\u9053\u9002\u914d\u5668 SPI&#xff08;Service Provider Interface&#xff09;&#xff0c;\u6240\u6709\u6e20\u9053\u9002\u914d\u5668\u5fc5\u987b\u5b9e\u73b0\u8be5\u63a5\u53e3&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u6e20\u9053\u9002\u914d\u5668\u6838\u5fc3\u63a5\u53e3<\/span><br \/>\n<span class=\"token attribute attr-name\">#[async_trait]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">trait<\/span> <span class=\"token type-definition class-name\">ChannelAdapter<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Send<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token class-name\">Sync<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u9002\u914d\u5668\u540d\u79f0<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">name<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u652f\u6301\u7684\u6e20\u9053\u7c7b\u578b<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">channel_type<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u521d\u59cb\u5316\u9002\u914d\u5668<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">initialize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">mut<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> config<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">AdapterConfig<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">AdapterError<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u542f\u52a8\u9002\u914d\u5668&#xff08;\u5f00\u59cb\u63a5\u6536\u6d88\u606f&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">start<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">mut<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">AdapterError<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u505c\u6b62\u9002\u914d\u5668<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">stop<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">mut<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">AdapterError<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; \u5165\u7ad9\u6d88\u606f\u5904\u7406 &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u63a5\u6536\u5916\u90e8\u6d88\u606f&#xff0c;\u8f6c\u6362\u4e3a\u5185\u90e8\u6807\u51c6\u683c\u5f0f<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">receive_message<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        raw_message<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">RawMessage<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">InboundMessage<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">AdapterError<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u9a8c\u8bc1\u6d88\u606f\u6765\u6e90\u5408\u6cd5\u6027&#xff08;\u7b7e\u540d\u6821\u9a8c\u7b49&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">verify_message<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        raw_message<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">RawMessage<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">AdapterError<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; \u51fa\u7ad9\u6d88\u606f\u5904\u7406 &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u5c06\u5185\u90e8\u6807\u51c6\u683c\u5f0f\u6d88\u606f\u8f6c\u6362\u4e3a\u76ee\u6807\u6e20\u9053\u683c\u5f0f<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">send_message<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        message<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">OutboundMessage<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">DeliveryReceipt<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">AdapterError<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u53d1\u9001\u6d41\u5f0f\u6d88\u606f&#xff08;SSE\/WebSocket&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">send_stream<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        stream<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">BoxStream<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token lifetime-annotation symbol\">&#039;static<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">StreamChunk<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        target<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">AdapterError<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; \u6e20\u9053\u80fd\u529b\u67e5\u8be2 &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u67e5\u8be2\u6e20\u9053\u652f\u6301\u7684\u80fd\u529b<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">capabilities<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">ChannelCapabilities<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u5065\u5eb7\u68c0\u67e5<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">health_check<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HealthStatus<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">AdapterError<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u6e20\u9053\u80fd\u529b\u63cf\u8ff0\u7ed3\u6784\u4f53\u5b9a\u4e49\u4e86\u6bcf\u4e2a\u5e73\u53f0\u652f\u6301\u7684\u529f\u80fd\u7279\u6027&#xff0c;\u9002\u914d\u5668\u5728\u521d\u59cb\u5316\u65f6\u58f0\u660e\u81ea\u8eab\u80fd\u529b&#xff0c;Gateway \u636e\u6b64\u505a\u80fd\u529b\u611f\u77e5\u8def\u7531&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u6e20\u9053\u80fd\u529b\u63cf\u8ff0<\/span><br \/>\n<span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ChannelCapabilities<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u652f\u6301\u6587\u672c\u6d88\u606f<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> text<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u652f\u6301\u56fe\u7247\u6d88\u606f<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> image<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u652f\u6301\u6587\u4ef6\u6d88\u606f<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> file<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u652f\u6301\u97f3\u9891\u6d88\u606f<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> audio<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u652f\u6301\u89c6\u9891\u6d88\u606f<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> video<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u652f\u6301\u6d41\u5f0f\u8f93\u51fa<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> streaming<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u652f\u6301\u5361\u7247\u6d88\u606f<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> card<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u652f\u6301\u6309\u94ae\u4ea4\u4e92<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> buttons<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u652f\u6301Markdown<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> markdown<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6700\u5927\u6d88\u606f\u957f\u5ea6<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> max_message_length<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u652f\u6301\u6d88\u606f\u7f16\u8f91<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> edit<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u652f\u6301\u6d88\u606f\u5220\u9664<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> delete<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u652f\u6301\u6d88\u606f\u5f15\u7528\u56de\u590d<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> reply<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u652f\u6301At\u63d0\u53ca<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> mention<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>3.1.2 \u9002\u914d\u5668\u6ce8\u518c\u4e0e\u52a0\u8f7d<\/h4>\n<p>\u9002\u914d\u5668\u901a\u8fc7\u5de5\u5382\u6a21\u5f0f\u521b\u5efa\u5b9e\u4f8b&#xff0c;\u5de5\u5382\u5728 Gateway \u542f\u52a8\u65f6\u81ea\u52a8\u6ce8\u518c&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u9002\u914d\u5668\u6ce8\u518c\u4e2d\u5fc3<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">AdapterRegistry<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5df2\u6ce8\u518c\u7684\u9002\u914d\u5668\u5de5\u5382<\/span><br \/>\n    factories<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Box<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">dyn<\/span> <span class=\"token class-name\">AdapterFactory<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6d3b\u8dc3\u7684\u9002\u914d\u5668\u5b9e\u4f8b<\/span><br \/>\n    instances<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">dyn<\/span> <span class=\"token class-name\">ChannelAdapter<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u914d\u7f6e\u4e2d\u5fc3<\/span><br \/>\n    config_source<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">dyn<\/span> <span class=\"token class-name\">ConfigSource<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[async_trait]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">trait<\/span> <span class=\"token type-definition class-name\">AdapterFactory<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Send<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token class-name\">Sync<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u521b\u5efa\u9002\u914d\u5668\u5b9e\u4f8b<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">create<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Box<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">dyn<\/span> <span class=\"token class-name\">ChannelAdapter<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u9002\u914d\u5668\u7c7b\u578b\u6807\u8bc6<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">channel_type<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">AdapterRegistry<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6ce8\u518c\u9002\u914d\u5668\u5de5\u5382<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">register_factory<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        factory<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Box<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">dyn<\/span> <span class=\"token class-name\">AdapterFactory<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">RegistryError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> channel_type <span class=\"token operator\">&#061;<\/span> factory<span class=\"token punctuation\">.<\/span><span class=\"token function\">channel_type<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> factories <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>factories<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        factories<span class=\"token punctuation\">.<\/span><span class=\"token function\">insert<\/span><span class=\"token punctuation\">(<\/span>channel_type<span class=\"token punctuation\">,<\/span> factory<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token namespace\">tracing<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">info!<\/span><span class=\"token punctuation\">(<\/span>channel <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">?<\/span>channel_type<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Adapter factory registered&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u83b7\u53d6\u6216\u521b\u5efa\u9002\u914d\u5668\u5b9e\u4f8b<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">get_or_create<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        channel_type<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">dyn<\/span> <span class=\"token class-name\">ChannelAdapter<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">RegistryError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u5148\u68c0\u67e5\u662f\u5426\u6709\u6d3b\u8dc3\u5b9e\u4f8b<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> instances <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>instances<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>instance<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> instances<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>channel_type<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>instance<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u521b\u5efa\u65b0\u5b9e\u4f8b<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> factories <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>factories<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> factory <span class=\"token operator\">&#061;<\/span> factories<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>channel_type<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">ok_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RegistryError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">FactoryNotFound<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">*<\/span>channel_type<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> adapter <span class=\"token operator\">&#061;<\/span> factory<span class=\"token punctuation\">.<\/span><span class=\"token function\">create<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> config <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>config_source<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">get_adapter_config<\/span><span class=\"token punctuation\">(<\/span>channel_type<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        adapter<span class=\"token punctuation\">.<\/span><span class=\"token function\">initialize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>config<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        adapter<span class=\"token punctuation\">.<\/span><span class=\"token function\">start<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> adapter<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">dyn<\/span> <span class=\"token class-name\">ChannelAdapter<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">from<\/span><span class=\"token punctuation\">(<\/span>adapter<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> instances <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>instances<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        instances<span class=\"token punctuation\">.<\/span><span class=\"token function\">insert<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">*<\/span>channel_type<span class=\"token punctuation\">,<\/span> adapter<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>adapter<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u4f18\u96c5\u505c\u6b62\u6307\u5b9a\u6e20\u9053\u7684\u9002\u914d\u5668<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">stop_adapter<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        channel_type<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">RegistryError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> instances <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>instances<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>adapter<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> instances<span class=\"token punctuation\">.<\/span><span class=\"token function\">remove<\/span><span class=\"token punctuation\">(<\/span>channel_type<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token comment\">\/\/ \u7b49\u5f85\u6b63\u5728\u5904\u7406\u7684\u6d88\u606f\u5b8c\u6210<\/span><br \/>\n            adapter<span class=\"token punctuation\">.<\/span><span class=\"token function\">stop<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token namespace\">tracing<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">info!<\/span><span class=\"token punctuation\">(<\/span>channel <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">?<\/span>channel_type<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Adapter stopped gracefully&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>3.1.3 \u9002\u914d\u5668\u5b9e\u73b0\u793a\u4f8b&#xff1a;\u98de\u4e66\u9002\u914d\u5668<\/h4>\n<p>\u4ee5\u4e0b\u662f\u4e00\u4e2a\u5b8c\u6574\u7684\u98de\u4e66\u6e20\u9053\u9002\u914d\u5668\u5b9e\u73b0\u793a\u4f8b&#xff0c;\u5c55\u793a\u4e86\u5982\u4f55\u5c06\u98de\u4e66\u7684\u4e8b\u4ef6\u56de\u8c03\u673a\u5236\u9002\u914d\u4e3a Gateway \u6807\u51c6\u63a5\u53e3&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u98de\u4e66\u9002\u914d\u5668\u5de5\u5382<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">FeishuAdapterFactory<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[async_trait]<\/span><br \/>\n<span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">AdapterFactory<\/span> <span class=\"token keyword\">for<\/span> <span class=\"token class-name\">FeishuAdapterFactory<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">create<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Box<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">dyn<\/span> <span class=\"token class-name\">ChannelAdapter<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">Box<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">FeishuAdapter<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">channel_type<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">ChannelType<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Feishu<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u98de\u4e66\u6e20\u9053\u9002\u914d\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">FeishuAdapter<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    app_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    app_secret<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    encrypt_key<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    verification_token<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    http_client<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">reqwest<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Client<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    tenant_access_token<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Instant<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[async_trait]<\/span><br \/>\n<span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">ChannelAdapter<\/span> <span class=\"token keyword\">for<\/span> <span class=\"token class-name\">FeishuAdapter<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">name<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token string\">&#034;feishu&#034;<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">channel_type<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">ChannelType<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Feishu<\/span> <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">initialize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">mut<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> config<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">AdapterConfig<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">AdapterError<\/span><span class=\"token operator\">&gt;<\/span><br \/>\n    <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>app_id <span class=\"token operator\">&#061;<\/span> config<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;app_id&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>app_secret <span class=\"token operator\">&#061;<\/span> config<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;app_secret&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>encrypt_key <span class=\"token operator\">&#061;<\/span> config<span class=\"token punctuation\">.<\/span><span class=\"token function\">get_optional<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;encrypt_key&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>verification_token <span class=\"token operator\">&#061;<\/span> config<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;verification_token&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">receive_message<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        raw<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">RawMessage<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">InboundMessage<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">AdapterError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> feishu_event<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">FeishuEvent<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token function\">from_slice<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>raw<span class=\"token punctuation\">.<\/span>body<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">map_err<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>e<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token class-name\">AdapterError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">ParseError<\/span><span class=\"token punctuation\">(<\/span>e<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">match<\/span> feishu_event<span class=\"token punctuation\">.<\/span>event_type<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_str<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token string\">&#034;im.message.receive_v1&#034;<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">let<\/span> msg_data <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>feishu_event<span class=\"token punctuation\">.<\/span>event<span class=\"token punctuation\">.<\/span>message<span class=\"token punctuation\">;<\/span><\/p>\n<p>                <span class=\"token comment\">\/\/ \u89e3\u6790\u6d88\u606f\u5185\u5bb9&#xff08;\u98de\u4e66\u6d88\u606f\u5185\u5bb9\u4e3aJSON\u5b57\u7b26\u4e32&#xff09;<\/span><br \/>\n                <span class=\"token keyword\">let<\/span> content<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">FeishuMessageContent<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token function\">from_str<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    <span class=\"token operator\">&amp;<\/span>msg_data<span class=\"token punctuation\">.<\/span>content<br \/>\n                <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or_default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>                <span class=\"token keyword\">let<\/span> normalized <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">NormalizedContent<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    text<span class=\"token punctuation\">:<\/span> content<span class=\"token punctuation\">.<\/span>text<span class=\"token punctuation\">.<\/span><span class=\"token function\">or_else<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span><span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                        <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token function\">from_str<\/span><span class=\"token punctuation\">::<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>msg_data<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">)<\/span><br \/>\n                            <span class=\"token punctuation\">.<\/span><span class=\"token function\">ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                            <span class=\"token punctuation\">.<\/span><span class=\"token function\">and_then<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>v<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> v<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;text&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                <span class=\"token punctuation\">.<\/span><span class=\"token function\">and_then<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>t<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> t<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_str<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">::<\/span>from<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    attachments<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">parse_feishu_attachments<\/span><span class=\"token punctuation\">(<\/span>msg_data<span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or_default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    mentions<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">parse_mentions<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>feishu_event<span class=\"token punctuation\">.<\/span>event<span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or_default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    reply_to<span class=\"token punctuation\">:<\/span> msg_data<span class=\"token punctuation\">.<\/span>parent_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>                <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">InboundMessage<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    source_message_id<span class=\"token punctuation\">:<\/span> msg_data<span class=\"token punctuation\">.<\/span>message_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    session_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    sender<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">SenderInfo<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                        user_id<span class=\"token punctuation\">:<\/span> feishu_event<span class=\"token punctuation\">.<\/span>event<span class=\"token punctuation\">.<\/span>sender<span class=\"token punctuation\">.<\/span>sender_id<span class=\"token punctuation\">.<\/span>open_id<span class=\"token punctuation\">,<\/span><br \/>\n                        user_name<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        avatar<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    content<span class=\"token punctuation\">:<\/span> normalized<span class=\"token punctuation\">,<\/span><br \/>\n                    metadata<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">InboundMetadata<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                        channel<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Feishu<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        chat_id<span class=\"token punctuation\">:<\/span> msg_data<span class=\"token punctuation\">.<\/span>chat_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        chat_type<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">parse_chat_type<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>msg_data<span class=\"token punctuation\">.<\/span>chat_type<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        timestamp<span class=\"token punctuation\">:<\/span> msg_data<span class=\"token punctuation\">.<\/span>create_time<span class=\"token punctuation\">.<\/span><span class=\"token function\">parse<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        raw_ref<span class=\"token punctuation\">:<\/span> raw<span class=\"token punctuation\">.<\/span>id<span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n            _ <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token class-name\">Err<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">AdapterError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">UnsupportedEventType<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                feishu_event<span class=\"token punctuation\">.<\/span>event_type<br \/>\n            <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">send_message<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        message<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">OutboundMessage<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">DeliveryReceipt<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">AdapterError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> token <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get_tenant_access_token<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u6839\u636e\u6e32\u67d3\u63d0\u793a\u9009\u62e9\u6d88\u606f\u683c\u5f0f<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token punctuation\">(<\/span>msg_type<span class=\"token punctuation\">,<\/span> content<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">match<\/span> message<span class=\"token punctuation\">.<\/span>render_hint<span class=\"token punctuation\">.<\/span>format <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">MessageFormat<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Markdown<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;text&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token string\">&#034;text&#034;<\/span><span class=\"token punctuation\">:<\/span> message<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">.<\/span>text<span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or_default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token class-name\">MessageFormat<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Interactive<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;interactive&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                 <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">build_feishu_card<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>message<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n            _ <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;text&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token string\">&#034;text&#034;<\/span><span class=\"token punctuation\">:<\/span> message<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">.<\/span>text<span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or_default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> req_body <span class=\"token operator\">&#061;<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token string\">&#034;receive_id&#034;<\/span><span class=\"token punctuation\">:<\/span> message<span class=\"token punctuation\">.<\/span>target<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;msg_type&#034;<\/span><span class=\"token punctuation\">:<\/span> msg_type<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;content&#034;<\/span><span class=\"token punctuation\">:<\/span> content<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> resp <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>http_client<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">post<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;https:\/\/open.feishu.cn\/open-apis\/im\/v1\/messages&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">header<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Authorization&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Bearer {}&#034;<\/span><span class=\"token punctuation\">,<\/span> token<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">header<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Content-Type&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;application\/json&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">query<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;receive_id_type&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;chat_id&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>req_body<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">send<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">map_err<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>e<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token class-name\">AdapterError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">SendError<\/span><span class=\"token punctuation\">(<\/span>e<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> resp_body<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span> <span class=\"token operator\">&#061;<\/span> resp<span class=\"token punctuation\">.<\/span><span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">map_err<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>e<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token class-name\">AdapterError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">SendError<\/span><span class=\"token punctuation\">(<\/span>e<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> message_id <span class=\"token operator\">&#061;<\/span> resp_body<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;data&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">and_then<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>d<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> d<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;message_id&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">and_then<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>m<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> m<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_str<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">DeliveryReceipt<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            message_id<span class=\"token punctuation\">,<\/span><br \/>\n            status<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">DeliveryStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Sent<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            timestamp<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Utc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">capabilities<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">ChannelCapabilities<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">ChannelCapabilities<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            text<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            image<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            file<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            audio<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            video<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            streaming<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            card<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            buttons<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            markdown<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            max_message_length<span class=\"token punctuation\">:<\/span> <span class=\"token number\">30000<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            edit<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            delete<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            reply<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            mention<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">health_check<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HealthStatus<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">AdapterError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u5c1d\u8bd5\u83b7\u53d6 tenant_access_token \u4f5c\u4e3a\u5065\u5eb7\u68c0\u67e5<\/span><br \/>\n        <span class=\"token keyword\">match<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get_tenant_access_token<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>_<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">HealthStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Healthy<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">Err<\/span><span class=\"token punctuation\">(<\/span>e<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">HealthStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Unhealthy<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                reason<span class=\"token punctuation\">:<\/span> e<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                since<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Utc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">FeishuAdapter<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u83b7\u53d6\u6216\u5237\u65b0 tenant_access_token<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">get_tenant_access_token<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">AdapterError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u68c0\u7f13\u5b58\u7684 token \u662f\u5426\u6709\u6548<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> cache <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>tenant_access_token<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>token<span class=\"token punctuation\">,<\/span> expiry<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> cache<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">if<\/span> expiry <span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">Instant<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>token<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u7533\u8bf7\u65b0 token<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> resp <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>http_client<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">post<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;https:\/\/open.feishu.cn\/open-apis\/auth\/v3\/tenant_access_token\/internal&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token string\">&#034;app_id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>app_id<span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;app_secret&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>app_secret<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">send<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">map_err<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>e<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token class-name\">AdapterError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">AuthError<\/span><span class=\"token punctuation\">(<\/span>e<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> body<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span> <span class=\"token operator\">&#061;<\/span> resp<span class=\"token punctuation\">.<\/span><span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">map_err<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>e<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token class-name\">AdapterError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">AuthError<\/span><span class=\"token punctuation\">(<\/span>e<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> token <span class=\"token operator\">&#061;<\/span> body<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;tenant_access_token&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">and_then<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>t<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> t<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_str<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">ok_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">AdapterError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">AuthError<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Missing token&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">into<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> expire <span class=\"token operator\">&#061;<\/span> body<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;expire&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">and_then<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>e<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> e<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_u64<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">7200<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u7f13\u5b58 token&#xff08;\u63d0\u524d60\u79d2\u8fc7\u671f&#xff09;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> cache <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>tenant_access_token<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token operator\">*<\/span>cache <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            token<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">Instant<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">from_secs<\/span><span class=\"token punctuation\">(<\/span>expire <span class=\"token operator\">&#8211;<\/span> <span class=\"token number\">60<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>token<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u6784\u5efa\u98de\u4e66\u4ea4\u4e92\u5361\u7247<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">build_feishu_card<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        message<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">OutboundMessage<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">AdapterError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> text <span class=\"token operator\">&#061;<\/span> message<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">.<\/span>text<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_deref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token string\">&#034;config&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token string\">&#034;wide_screen_mode&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;elements&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">[<\/span><br \/>\n                <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token string\">&#034;tag&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;div&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token string\">&#034;text&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                        <span class=\"token string\">&#034;content&#034;<\/span><span class=\"token punctuation\">:<\/span> text<span class=\"token punctuation\">,<\/span><br \/>\n                        <span class=\"token string\">&#034;tag&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;lark_md&#034;<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">]<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h3>3.2 \u6d88\u606f\u683c\u5f0f\u5f52\u4e00\u5316\u6d41\u7a0b<\/h3>\n<h4>3.2.1 \u5f52\u4e00\u5316\u7ba1\u7ebf<\/h4>\n<p>\u6d88\u606f\u4ece\u5916\u90e8\u6e20\u9053\u8fdb\u5165 Gateway \u540e&#xff0c;\u9700\u8981\u7ecf\u8fc7\u4e00\u6761\u5f52\u4e00\u5316\u7ba1\u7ebf&#xff0c;\u5c06\u5f02\u6784\u683c\u5f0f\u7edf\u4e00\u4e3a\u5185\u90e8\u6807\u51c6\u683c\u5f0f&#xff1a;<\/p>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502                     \u6d88\u606f\u683c\u5f0f\u5f52\u4e00\u5316\u7ba1\u7ebf                                  \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510         \u2502<br \/>\n\u2502  \u2502 \u539f\u59cb\u6d88\u606f  \u2502\u2500\u2500&gt;\u2502 \u5b89\u5168\u9a8c\u8bc1  \u2502\u2500\u2500&gt;\u2502 \u683c\u5f0f\u89e3\u6790  \u2502\u2500\u2500&gt;\u2502 \u5185\u5bb9\u5f52\u4e00\u5316\u2502         \u2502<br \/>\n\u2502  \u2502 (Raw)    \u2502   \u2502 (Verify) \u2502   \u2502 (Parse)  \u2502   \u2502 (Normalize)\u2502       \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518         \u2502<br \/>\n\u2502                                                    \u2502                \u2502<br \/>\n\u2502                                                    v                \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510         \u2502<br \/>\n\u2502  \u2502 \u6d88\u606f\u5206\u53d1  \u2502&lt;\u2500\u2500\u2502 \u5143\u6570\u636e   \u2502&lt;\u2500\u2500\u2502 \u5185\u5bb9\u589e\u5f3a  \u2502&lt;\u2500\u2500\u2502 \u6807\u51c6\u6d88\u606f  \u2502         \u2502<br \/>\n\u2502  \u2502 (Dispatch)\u2502   \u2502 (Enrich) \u2502   \u2502 (Enhance)\u2502   \u2502 (Standard)\u2502        \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518         \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u5f52\u4e00\u5316\u6b65\u9aa4\u8be6\u89e3:                                                       \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  1. \u5b89\u5168\u9a8c\u8bc1: \u7b7e\u540d\u6821\u9a8c \u2192 \u9891\u7387\u9650\u5236 \u2192 \u5185\u5bb9\u5b89\u5168\u68c0\u67e5                       \u2502<br \/>\n\u2502  2. \u683c\u5f0f\u89e3\u6790: JSON\/XML\/Form \u89e3\u6790 \u2192 \u6e20\u9053\u7279\u5b9a\u7ed3\u6784\u63d0\u53d6                    \u2502<br \/>\n\u2502  3. \u5185\u5bb9\u5f52\u4e00\u5316: \u6587\u672c\u63d0\u53d6 \u2192 \u9644\u4ef6\u4e0b\u8f7d \u2192 \u591a\u6a21\u6001\u8f6c\u6362                       \u2502<br \/>\n\u2502  4. \u5185\u5bb9\u589e\u5f3a: \u8bed\u8a00\u68c0\u6d4b \u2192 \u610f\u56fe\u9884\u5224 \u2192 \u4e0a\u4e0b\u6587\u5173\u8054                         \u2502<br \/>\n\u2502  5. \u5143\u6570\u636e\u586b\u5145: \u65f6\u95f4\u6233\u6807\u51c6\u5316 \u2192 \u7528\u6237\u4fe1\u606f\u8865\u5168 \u2192 \u4f1a\u8bdd\u6620\u5c04                  \u2502<br \/>\n\u2502  6. \u6d88\u606f\u5206\u53d1: \u8def\u7531\u5230\u4f1a\u8bdd\u7ba1\u7406\u5668 \u2192 \u8fdb\u5165\u5904\u7406\u7ba1\u7ebf                          \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<h4>3.2.2 \u5f52\u4e00\u5316\u5904\u7406\u5668\u5b9e\u73b0<\/h4>\n<p>\u5f52\u4e00\u5316\u7ba1\u7ebf\u91c7\u7528\u8d23\u4efb\u94fe\u6a21\u5f0f&#xff0c;\u6bcf\u4e2a\u9636\u6bb5\u72ec\u7acb\u5904\u7406\u5e76\u4f20\u9012\u7ed9\u4e0b\u4e00\u9636\u6bb5&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u6d88\u606f\u5f52\u4e00\u5316\u7ba1\u7ebf<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">NormalizationPipeline<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    stages<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Box<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">dyn<\/span> <span class=\"token class-name\">NormalizationStage<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[async_trait]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">trait<\/span> <span class=\"token type-definition class-name\">NormalizationStage<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Send<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token class-name\">Sync<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">name<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">process<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        message<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">mut<\/span> <span class=\"token class-name\">PipelineMessage<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">PipelineError<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u5f52\u4e00\u5316\u7ba1\u7ebf\u6d88\u606f&#xff08;\u5728\u7ba1\u7ebf\u5404\u9636\u6bb5\u95f4\u4f20\u9012&#xff09;<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">PipelineMessage<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> raw<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">RawMessage<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> verified<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> parsed<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ParsedMessage<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> normalized<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">NormalizedContent<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> enriched<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">EnrichedContent<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> inbound<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">InboundMessage<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">NormalizationPipeline<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">execute<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        raw<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">RawMessage<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">InboundMessage<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">PipelineError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> message <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">PipelineMessage<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            raw<span class=\"token punctuation\">,<\/span><br \/>\n            verified<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            parsed<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            normalized<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            enriched<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            inbound<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">for<\/span> stage <span class=\"token keyword\">in<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>stages <span class=\"token punctuation\">{<\/span><br \/>\n            stage<span class=\"token punctuation\">.<\/span><span class=\"token function\">process<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">mut<\/span> message<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">map_err<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>e<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token namespace\">tracing<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">error!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    stage <span class=\"token operator\">&#061;<\/span> stage<span class=\"token punctuation\">.<\/span><span class=\"token function\">name<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    error <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">%<\/span>e<span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token string\">&#034;Pipeline stage failed&#034;<\/span><br \/>\n                <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                e<br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        message<span class=\"token punctuation\">.<\/span>inbound<span class=\"token punctuation\">.<\/span><span class=\"token function\">ok_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PipelineError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">IncompletePipeline<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u4ee5\u4e0b\u662f\u4e24\u4e2a\u5173\u952e\u9636\u6bb5\u7684\u5b9e\u73b0&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u9636\u6bb51&#xff1a;\u5b89\u5168\u9a8c\u8bc1<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">SecurityVerificationStage<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    rate_limiter<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RateLimiter<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    content_safety<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ContentSafetyChecker<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[async_trait]<\/span><br \/>\n<span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">NormalizationStage<\/span> <span class=\"token keyword\">for<\/span> <span class=\"token class-name\">SecurityVerificationStage<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">name<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token string\">&#034;security_verification&#034;<\/span> <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">process<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> msg<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">mut<\/span> <span class=\"token class-name\">PipelineMessage<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">PipelineError<\/span><span class=\"token operator\">&gt;<\/span><br \/>\n    <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u9891\u7387\u9650\u5236\u68c0\u67e5<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>rate_limiter<span class=\"token punctuation\">.<\/span><span class=\"token function\">check<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>msg<span class=\"token punctuation\">.<\/span>raw<span class=\"token punctuation\">.<\/span>source<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u5185\u5bb9\u5b89\u5168\u68c0\u67e5&#xff08;\u654f\u611f\u8bcd\u3001\u6076\u610f\u94fe\u63a5\u7b49&#xff09;<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>text<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>msg<span class=\"token punctuation\">.<\/span>raw<span class=\"token punctuation\">.<\/span>text_preview <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>content_safety<span class=\"token punctuation\">.<\/span><span class=\"token function\">check<\/span><span class=\"token punctuation\">(<\/span>text<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        msg<span class=\"token punctuation\">.<\/span>verified <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u9636\u6bb53&#xff1a;\u5185\u5bb9\u5f52\u4e00\u5316<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ContentNormalizationStage<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    attachment_downloader<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">AttachmentDownloader<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    media_processor<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">MediaProcessor<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[async_trait]<\/span><br \/>\n<span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">NormalizationStage<\/span> <span class=\"token keyword\">for<\/span> <span class=\"token class-name\">ContentNormalizationStage<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">name<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token string\">&#034;content_normalization&#034;<\/span> <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">process<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> msg<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">mut<\/span> <span class=\"token class-name\">PipelineMessage<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">PipelineError<\/span><span class=\"token operator\">&gt;<\/span><br \/>\n    <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> parsed <span class=\"token operator\">&#061;<\/span> msg<span class=\"token punctuation\">.<\/span>parsed<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> attachments <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">for<\/span> att <span class=\"token keyword\">in<\/span> <span class=\"token operator\">&amp;<\/span>parsed<span class=\"token punctuation\">.<\/span>attachments <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">match<\/span> att<span class=\"token punctuation\">.<\/span>att_type <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token class-name\">AttachmentType<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Image<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">let<\/span> downloaded <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>attachment_downloader<br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">download<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>att<span class=\"token punctuation\">.<\/span>url<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    <span class=\"token keyword\">let<\/span> processed <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>media_processor<br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">process_image<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>downloaded<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    attachments<span class=\"token punctuation\">.<\/span><span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">NormalizedAttachment<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                        att_type<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">AttachmentType<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Image<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        url<span class=\"token punctuation\">:<\/span> processed<span class=\"token punctuation\">.<\/span>url<span class=\"token punctuation\">,<\/span><br \/>\n                        thumbnail_url<span class=\"token punctuation\">:<\/span> processed<span class=\"token punctuation\">.<\/span>thumbnail_url<span class=\"token punctuation\">,<\/span><br \/>\n                        metadata<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n                            <span class=\"token string\">&#034;width&#034;<\/span><span class=\"token punctuation\">:<\/span> processed<span class=\"token punctuation\">.<\/span>width<span class=\"token punctuation\">,<\/span><br \/>\n                            <span class=\"token string\">&#034;height&#034;<\/span><span class=\"token punctuation\">:<\/span> processed<span class=\"token punctuation\">.<\/span>height<span class=\"token punctuation\">,<\/span><br \/>\n                            <span class=\"token string\">&#034;size&#034;<\/span><span class=\"token punctuation\">:<\/span> processed<span class=\"token punctuation\">.<\/span>size<span class=\"token punctuation\">,<\/span><br \/>\n                        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token class-name\">AttachmentType<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">File<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">let<\/span> downloaded <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>attachment_downloader<br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">download<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>att<span class=\"token punctuation\">.<\/span>url<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    attachments<span class=\"token punctuation\">.<\/span><span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">NormalizedAttachment<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                        att_type<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">AttachmentType<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">File<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        url<span class=\"token punctuation\">:<\/span> downloaded<span class=\"token punctuation\">.<\/span>url<span class=\"token punctuation\">,<\/span><br \/>\n                        thumbnail_url<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        metadata<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n                            <span class=\"token string\">&#034;filename&#034;<\/span><span class=\"token punctuation\">:<\/span> att<span class=\"token punctuation\">.<\/span>filename<span class=\"token punctuation\">,<\/span><br \/>\n                            <span class=\"token string\">&#034;size&#034;<\/span><span class=\"token punctuation\">:<\/span> att<span class=\"token punctuation\">.<\/span>size<span class=\"token punctuation\">,<\/span><br \/>\n                            <span class=\"token string\">&#034;mime_type&#034;<\/span><span class=\"token punctuation\">:<\/span> att<span class=\"token punctuation\">.<\/span>mime_type<span class=\"token punctuation\">,<\/span><br \/>\n                        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n                _ <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    attachments<span class=\"token punctuation\">.<\/span><span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">NormalizedAttachment<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                        att_type<span class=\"token punctuation\">:<\/span> att<span class=\"token punctuation\">.<\/span>att_type<span class=\"token punctuation\">,<\/span><br \/>\n                        url<span class=\"token punctuation\">:<\/span> att<span class=\"token punctuation\">.<\/span>url<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        thumbnail_url<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        metadata<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        msg<span class=\"token punctuation\">.<\/span>normalized <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">NormalizedContent<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            text<span class=\"token punctuation\">:<\/span> parsed<span class=\"token punctuation\">.<\/span>text<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            attachments<span class=\"token punctuation\">,<\/span><br \/>\n            mentions<span class=\"token punctuation\">:<\/span> parsed<span class=\"token punctuation\">.<\/span>mentions<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            reply_to<span class=\"token punctuation\">:<\/span> parsed<span class=\"token punctuation\">.<\/span>reply_to<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>3.2.3 \u5185\u5bb9\u589e\u5f3a\u9636\u6bb5<\/h4>\n<p>\u5185\u5bb9\u589e\u5f3a\u662f\u5f52\u4e00\u5316\u7ba1\u7ebf\u4e2d\u6700\u5177\u667a\u80fd\u6027\u7684\u9636\u6bb5&#xff0c;\u5b83\u5728\u6d88\u606f\u8fdb\u5165\u6838\u5fc3\u5904\u7406\u4e4b\u524d\u5b8c\u6210\u9884\u5206\u6790&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u9636\u6bb54&#xff1a;\u5185\u5bb9\u589e\u5f3a<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ContentEnhancementStage<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    language_detector<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">LanguageDetector<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    intent_predictor<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">IntentPredictor<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    session_resolver<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SessionResolver<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[async_trait]<\/span><br \/>\n<span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">NormalizationStage<\/span> <span class=\"token keyword\">for<\/span> <span class=\"token class-name\">ContentEnhancementStage<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">name<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token string\">&#034;content_enhancement&#034;<\/span> <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">process<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> msg<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">mut<\/span> <span class=\"token class-name\">PipelineMessage<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">PipelineError<\/span><span class=\"token operator\">&gt;<\/span><br \/>\n    <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> normalized <span class=\"token operator\">&#061;<\/span> msg<span class=\"token punctuation\">.<\/span>normalized<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8bed\u8a00\u68c0\u6d4b<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> language <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>text<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>normalized<span class=\"token punctuation\">.<\/span>text <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>language_detector<span class=\"token punctuation\">.<\/span><span class=\"token function\">detect<\/span><span class=\"token punctuation\">(<\/span>text<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">Language<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Unknown<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u5feb\u901f\u610f\u56fe\u9884\u5224&#xff08;\u8f7b\u91cf\u7ea7\u6a21\u578b&#xff0c;\u4ec5\u7528\u4e8e\u8def\u7531\u63d0\u793a&#xff09;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> intent_hint <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>text<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>normalized<span class=\"token punctuation\">.<\/span>text <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>intent_predictor<span class=\"token punctuation\">.<\/span><span class=\"token function\">quick_predict<\/span><span class=\"token punctuation\">(<\/span>text<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">None<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u4f1a\u8bdd\u89e3\u6790&#xff1a;\u6839\u636e\u6e20\u9053ID&#043;\u7528\u6237ID\u67e5\u627e\u6216\u521b\u5efa\u4f1a\u8bdd<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> session_id <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>session_resolver<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">resolve_or_create<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>msg<span class=\"token punctuation\">.<\/span>raw<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        msg<span class=\"token punctuation\">.<\/span>enriched <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnrichedContent<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            language<span class=\"token punctuation\">,<\/span><br \/>\n            intent_hint<span class=\"token punctuation\">,<\/span><br \/>\n            session_id<span class=\"token punctuation\">,<\/span><br \/>\n            priority<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">calculate_priority<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>normalized<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u5185\u5bb9\u589e\u5f3a\u9636\u6bb5\u7684\u8bbe\u8ba1\u4ef7\u503c\u5728\u4e8e&#xff1a;\u901a\u8fc7\u5c06\u8bed\u8a00\u68c0\u6d4b\u3001\u610f\u56fe\u9884\u5224\u7b49\u8f7b\u91cf\u7ea7\u5206\u6790\u524d\u7f6e\u5230\u5f52\u4e00\u5316\u7ba1\u7ebf&#xff0c;\u6838\u5fc3\u8def\u7531\u5f15\u64ce\u53ef\u4ee5\u76f4\u63a5\u5229\u7528\u8fd9\u4e9b\u9884\u8ba1\u7b97\u7ed3\u679c&#xff0c;\u51cf\u5c11\u91cd\u590d\u8ba1\u7b97&#xff0c;\u63d0\u5347\u6574\u4f53\u5904\u7406\u6548\u7387\u3002<\/p>\n<h3>3.3 \u591a\u5e73\u53f0\u534f\u8bae\u5dee\u5f02\u5904\u7406<\/h3>\n<h4>3.3.1 \u5e73\u53f0\u5dee\u5f02\u5bf9\u6bd4\u77e9\u9635<\/h4>\n<p>\u4ee5\u4e0b\u662f Hermes Agent \u652f\u6301\u7684\u5404\u4e3b\u6d41\u5e73\u53f0\u5728\u5173\u952e\u534f\u8bae\u7ef4\u5ea6\u7684\u5dee\u5f02\u5bf9\u6bd4&#xff1a;<\/p>\n<table>\n<tr>\u5e73\u53f0\u6d88\u606f\u683c\u5f0f\u6700\u5927\u957f\u5ea6\u6d41\u5f0f\u652f\u6301\u5bcc\u6587\u672c\u5361\u7247\/\u6309\u94ae\u9644\u4ef6\u7c7b\u578b\u56de\u8c03\u673a\u5236\u9274\u6743\u65b9\u5f0f<\/tr>\n<tbody>\n<tr>\n<td>Web UI<\/td>\n<td>JSON<\/td>\n<td>\u65e0\u9650\u5236<\/td>\n<td>SSE\/WS<\/td>\n<td>Markdown<\/td>\n<td>\u81ea\u5b9a\u4e49\u7ec4\u4ef6<\/td>\n<td>\u5168\u7c7b\u578b<\/td>\n<td>WebSocket<\/td>\n<td>JWT<\/td>\n<\/tr>\n<tr>\n<td>\u98de\u4e66<\/td>\n<td>JSON<\/td>\n<td>30K<\/td>\n<td>\u5426<\/td>\n<td>Markdown<\/td>\n<td>\u4ea4\u4e92\u5361\u7247<\/td>\n<td>\u56fe\u7247\/\u6587\u4ef6<\/td>\n<td>Webhook<\/td>\n<td>App Token<\/td>\n<\/tr>\n<tr>\n<td>\u9489\u9489<\/td>\n<td>JSON<\/td>\n<td>20K<\/td>\n<td>\u5426<\/td>\n<td>Markdown<\/td>\n<td>ActionCard<\/td>\n<td>\u56fe\u7247\/\u6587\u4ef6<\/td>\n<td>Webhook<\/td>\n<td>AppKey\/Secret<\/td>\n<\/tr>\n<tr>\n<td>\u4f01\u4e1a\u5fae\u4fe1<\/td>\n<td>XML\/JSON<\/td>\n<td>2K<\/td>\n<td>\u5426<\/td>\n<td>\u5426<\/td>\n<td>\u6587\u672c\u5361\u7247<\/td>\n<td>\u56fe\u7247\/\u6587\u4ef6<\/td>\n<td>Webhook<\/td>\n<td>Token&#043;AES<\/td>\n<\/tr>\n<tr>\n<td>Slack<\/td>\n<td>JSON<\/td>\n<td>40K<\/td>\n<td>\u5426<\/td>\n<td>mrkdwn<\/td>\n<td>Blocks API<\/td>\n<td>\u5168\u7c7b\u578b<\/td>\n<td>Events API<\/td>\n<td>OAuth Token<\/td>\n<\/tr>\n<tr>\n<td>Telegram<\/td>\n<td>JSON<\/td>\n<td>4096<\/td>\n<td>\u662f(\u6d41\u5f0f\u7f16\u8f91)<\/td>\n<td>HTML\/MD<\/td>\n<td>Inline KB<\/td>\n<td>\u5168\u7c7b\u578b<\/td>\n<td>Long Polling<\/td>\n<td>Bot Token<\/td>\n<\/tr>\n<tr>\n<td>Discord<\/td>\n<td>JSON<\/td>\n<td>2000<\/td>\n<td>\u662f(\u6d41\u5f0f\u7f16\u8f91)<\/td>\n<td>Markdown<\/td>\n<td>Components<\/td>\n<td>\u5168\u7c7b\u578b<\/td>\n<td>Gateway WS<\/td>\n<td>Bot Token<\/td>\n<\/tr>\n<tr>\n<td>Email<\/td>\n<td>MIME<\/td>\n<td>\u65e0\u9650\u5236<\/td>\n<td>\u5426<\/td>\n<td>HTML<\/td>\n<td>\u5426<\/td>\n<td>\u5168\u7c7b\u578b<\/td>\n<td>IMAP\/SMTP<\/td>\n<td>SMTP Auth<\/td>\n<\/tr>\n<tr>\n<td>WhatsApp<\/td>\n<td>JSON<\/td>\n<td>65536<\/td>\n<td>\u5426<\/td>\n<td>\u5426<\/td>\n<td>\u6a21\u677f\u6309\u94ae<\/td>\n<td>\u56fe\u7247\/\u6587\u6863<\/td>\n<td>Webhook<\/td>\n<td>Bearer Token<\/td>\n<\/tr>\n<tr>\n<td>Teams<\/td>\n<td>JSON<\/td>\n<td>28K<\/td>\n<td>\u5426<\/td>\n<td>Markdown<\/td>\n<td>Adaptive Card<\/td>\n<td>\u5168\u7c7b\u578b<\/td>\n<td>Webhook<\/td>\n<td>OAuth<\/td>\n<\/tr>\n<tr>\n<td>Telegram Bot<\/td>\n<td>JSON<\/td>\n<td>4096<\/td>\n<td>\u662f<\/td>\n<td>HTML\/MD<\/td>\n<td>Inline KB<\/td>\n<td>\u5168\u7c7b\u578b<\/td>\n<td>Webhook\/Poll<\/td>\n<td>Bot Token<\/td>\n<\/tr>\n<tr>\n<td>Twitter DM<\/td>\n<td>JSON<\/td>\n<td>10000<\/td>\n<td>\u5426<\/td>\n<td>\u5426<\/td>\n<td>Quick Reply<\/td>\n<td>\u56fe\u7247\/\u89c6\u9891<\/td>\n<td>Webhook<\/td>\n<td>OAuth 1.0a<\/td>\n<\/tr>\n<tr>\n<td>API\/SDK<\/td>\n<td>JSON<\/td>\n<td>\u65e0\u9650\u5236<\/td>\n<td>\u662f<\/td>\n<td>\u539f\u59cb<\/td>\n<td>\u539f\u59cb<\/td>\n<td>\u5168\u7c7b\u578b<\/td>\n<td>HTTP\u56de\u8c03<\/td>\n<td>API Key<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>3.3.2 \u534f\u8bae\u5dee\u5f02\u5904\u7406\u7b56\u7565<\/h4>\n<p>\u9762\u5bf9\u5982\u6b64\u591a\u6837\u7684\u5e73\u53f0\u534f\u8bae\u5dee\u5f02&#xff0c;Gateway \u91c7\u7528\u4e86\u4e09\u5c42\u5904\u7406\u7b56\u7565&#xff1a;<\/p>\n<p>\u7b2c\u4e00\u5c42&#xff1a;\u683c\u5f0f\u9002\u914d\u5c42\u3002\u6bcf\u4e2a\u9002\u914d\u5668\u8d1f\u8d23\u5c06\u5e73\u53f0\u7279\u5b9a\u683c\u5f0f\u89e3\u6790\u4e3a\u5185\u90e8\u6807\u51c6\u683c\u5f0f\u3002\u4f8b\u5982&#xff0c;\u98de\u4e66\u7684\u6d88\u606f\u5185\u5bb9\u662f JSON \u5b57\u7b26\u4e32\u5d4c\u5957\u5728 JSON \u4e2d&#xff0c;\u9489\u9489\u4f7f\u7528\u4e0d\u540c\u7684\u5b57\u6bb5\u547d\u540d&#xff0c;\u4f01\u4e1a\u5fae\u4fe1\u53ef\u80fd\u4f7f\u7528 XML \u683c\u5f0f\u3002\u9002\u914d\u5668\u5185\u90e8\u5904\u7406\u8fd9\u4e9b\u683c\u5f0f\u5dee\u5f02&#xff0c;\u5bf9\u5916\u8f93\u51fa\u7edf\u4e00\u7684 NormalizedContent\u3002<\/p>\n<p>\u7b2c\u4e8c\u5c42&#xff1a;\u80fd\u529b\u964d\u7ea7\u5c42\u3002\u5f53 Agent \u4ea7\u751f\u7684\u8f93\u51fa\u5185\u5bb9\u8d85\u51fa\u76ee\u6807\u6e20\u9053\u7684\u80fd\u529b\u9650\u5236\u65f6&#xff08;\u5982\u98de\u4e66\u4e0d\u652f\u6301\u6d41\u5f0f\u8f93\u51fa\u3001\u4f01\u4e1a\u5fae\u4fe1\u4e0d\u652f\u6301 Markdown&#xff09;&#xff0c;Gateway \u81ea\u52a8\u6267\u884c\u80fd\u529b\u964d\u7ea7&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u80fd\u529b\u964d\u7ea7\u5904\u7406\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">CapabilityDegrader<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5404\u6e20\u9053\u80fd\u529b\u7f13\u5b58<\/span><br \/>\n    capabilities_cache<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">ChannelCapabilities<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">CapabilityDegrader<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6839\u636e\u76ee\u6807\u6e20\u9053\u80fd\u529b\u964d\u7ea7\u8f93\u51fa\u5185\u5bb9<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">degrade<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        content<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">NormalizedContent<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        target_channel<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">NormalizedContent<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">DegradeError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> caps <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>capabilities_cache<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>target_channel<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">cloned<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">ok_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">DegradeError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">UnknownChannel<\/span><span class=\"token punctuation\">(<\/span>target_channel<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> degraded <span class=\"token operator\">&#061;<\/span> content<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ Markdown \u964d\u7ea7<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token operator\">!<\/span>caps<span class=\"token punctuation\">.<\/span>markdown <span class=\"token operator\">&amp;&amp;<\/span> degraded<span class=\"token punctuation\">.<\/span>text<span class=\"token punctuation\">.<\/span><span class=\"token function\">is_some<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> plain <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">strip_markdown<\/span><span class=\"token punctuation\">(<\/span>degraded<span class=\"token punctuation\">.<\/span>text<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            degraded<span class=\"token punctuation\">.<\/span>text <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>plain<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u6d88\u606f\u957f\u5ea6\u622a\u65ad<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>text<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>degraded<span class=\"token punctuation\">.<\/span>text <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> text<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;<\/span> caps<span class=\"token punctuation\">.<\/span>max_message_length <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">let<\/span> truncated <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">smart_truncate<\/span><span class=\"token punctuation\">(<\/span>text<span class=\"token punctuation\">,<\/span> caps<span class=\"token punctuation\">.<\/span>max_message_length<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                degraded<span class=\"token punctuation\">.<\/span>text <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>truncated<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u9644\u4ef6\u7c7b\u578b\u8fc7\u6ee4<\/span><br \/>\n        degraded<span class=\"token punctuation\">.<\/span>attachments<span class=\"token punctuation\">.<\/span><span class=\"token function\">retain<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>att<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">match<\/span> att<span class=\"token punctuation\">.<\/span>att_type <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token class-name\">AttachmentType<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Image<\/span> <span class=\"token operator\">&#061;&gt;<\/span> caps<span class=\"token punctuation\">.<\/span>image<span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token class-name\">AttachmentType<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">File<\/span> <span class=\"token operator\">&#061;&gt;<\/span> caps<span class=\"token punctuation\">.<\/span>file<span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token class-name\">AttachmentType<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Audio<\/span> <span class=\"token operator\">&#061;&gt;<\/span> caps<span class=\"token punctuation\">.<\/span>audio<span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token class-name\">AttachmentType<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Video<\/span> <span class=\"token operator\">&#061;&gt;<\/span> caps<span class=\"token punctuation\">.<\/span>video<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>degraded<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u667a\u80fd\u622a\u65ad&#xff08;\u5728\u53e5\u5b50\u8fb9\u754c\u622a\u65ad&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">smart_truncate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> text<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span><span class=\"token punctuation\">,<\/span> max_len<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> text<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&lt;&#061;<\/span> max_len <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> text<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> truncated <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>text<span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">..<\/span>max_len<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u5c1d\u8bd5\u5728\u6700\u540e\u4e00\u4e2a\u53e5\u53f7\/\u6362\u884c\u5904\u622a\u65ad<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>pos<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> truncated<span class=\"token punctuation\">.<\/span><span class=\"token function\">rfind<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>c<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">char<\/span><span class=\"token closure-punctuation punctuation\">|<\/span><\/span> c <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token char\">&#039;\\\\n&#039;<\/span> <span class=\"token operator\">||<\/span> c <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token char\">&#039;\u3002&#039;<\/span> <span class=\"token operator\">||<\/span> c <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token char\">&#039;.&#039;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> result <span class=\"token operator\">&#061;<\/span> truncated<span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">..<\/span>pos<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            result<span class=\"token punctuation\">.<\/span><span class=\"token function\">push_str<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\\\\n&#8230;[\u6d88\u606f\u5df2\u622a\u65ad]&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            result<br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> result <span class=\"token operator\">&#061;<\/span> truncated<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            result<span class=\"token punctuation\">.<\/span><span class=\"token function\">push_str<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;&#8230;[\u6d88\u606f\u5df2\u622a\u65ad]&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            result<br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u53bb\u9664 Markdown \u683c\u5f0f\u6807\u8bb0<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">strip_markdown<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> text<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        text<span class=\"token punctuation\">.<\/span><span class=\"token function\">replace<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;**&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">replace<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;*&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">replace<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;&#096;&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">replace<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;#&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">replace<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;&gt;&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">replace<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;-&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;\u2022&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">replace<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;[&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">replace<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;]&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u7b2c\u4e09\u5c42&#xff1a;\u534f\u8bae\u8865\u507f\u5c42\u3002\u5bf9\u4e8e\u67d0\u4e9b\u6e20\u9053\u4e0d\u652f\u6301\u7684\u529f\u80fd&#xff0c;Gateway \u63d0\u4f9b\u534f\u8bae\u7ea7\u8865\u507f\u3002\u4f8b\u5982&#xff0c;\u5f53\u76ee\u6807\u6e20\u9053\u4e0d\u652f\u6301\u6d41\u5f0f\u8f93\u51fa\u65f6&#xff0c;Gateway \u5c06\u6d41\u5f0f\u8f93\u51fa\u7f13\u5b58\u4e3a\u5b8c\u6574\u6d88\u606f\u540e\u4e00\u6b21\u6027\u53d1\u9001&#xff1b;\u5f53\u6e20\u9053\u4e0d\u652f\u6301\u6d88\u606f\u7f16\u8f91\u65f6&#xff0c;Gateway \u901a\u8fc7\u53d1\u9001\u65b0\u6d88\u606f&#043;\u5220\u9664\u65e7\u6d88\u606f\u7684\u65b9\u5f0f\u6a21\u62df\u7f16\u8f91\u6548\u679c\u3002<\/p>\n<h4>3.3.3 \u6d88\u606f\u957f\u5ea6\u8d85\u9650\u5904\u7406<\/h4>\n<p>\u4e0d\u540c\u5e73\u53f0\u5bf9\u6d88\u606f\u957f\u5ea6\u6709\u4e0d\u540c\u9650\u5236&#xff0c;\u5f53 Agent \u4ea7\u751f\u7684\u56de\u590d\u8d85\u8fc7\u9650\u5236\u65f6&#xff0c;Gateway \u91c7\u7528\u5206\u7247\u53d1\u9001\u7b56\u7565&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u6d88\u606f\u5206\u7247\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">MessageSplitter<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5404\u6e20\u9053\u6700\u5927\u6d88\u606f\u957f\u5ea6<\/span><br \/>\n    max_lengths<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5206\u7247\u7b56\u7565<\/span><br \/>\n    strategy<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">SplitStrategy<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">SplitStrategy<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6309\u6bb5\u843d\u5206\u7247<\/span><br \/>\n    <span class=\"token class-name\">ByParagraph<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6309\u53e5\u5b50\u5206\u7247<\/span><br \/>\n    <span class=\"token class-name\">BySentence<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6309\u4ee3\u7801\u5757\u8fb9\u754c\u5206\u7247<\/span><br \/>\n    <span class=\"token class-name\">ByCodeBlock<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u667a\u80fd\u5206\u7247&#xff08;\u7efc\u5408\u8003\u8651\u591a\u79cd\u8fb9\u754c&#xff09;<\/span><br \/>\n    <span class=\"token class-name\">Smart<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">MessageSplitter<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">split<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        content<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        channel<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> max_len <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>max_lengths<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>channel<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">copied<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">4000<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> content<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&lt;&#061;<\/span> max_len <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span>content<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">match<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>strategy <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">SplitStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Smart<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">smart_split<\/span><span class=\"token punctuation\">(<\/span>content<span class=\"token punctuation\">,<\/span> max_len<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">SplitStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">ByParagraph<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">split_by_delimiter<\/span><span class=\"token punctuation\">(<\/span>content<span class=\"token punctuation\">,<\/span> max_len<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;\\\\n\\\\n&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">SplitStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">BySentence<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">split_by_delimiter<\/span><span class=\"token punctuation\">(<\/span>content<span class=\"token punctuation\">,<\/span> max_len<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;\u3002&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">SplitStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">ByCodeBlock<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">split_by_code_block<\/span><span class=\"token punctuation\">(<\/span>content<span class=\"token punctuation\">,<\/span> max_len<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">smart_split<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> content<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span><span class=\"token punctuation\">,<\/span> max_len<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> chunks <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> current <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u6309\u884c\u904d\u5386&#xff0c;\u4f18\u5148\u5728\u4ee3\u7801\u5757\u8fb9\u754c\u5206\u7247<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> in_code_block <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">for<\/span> line <span class=\"token keyword\">in<\/span> content<span class=\"token punctuation\">.<\/span><span class=\"token function\">lines<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> line<span class=\"token punctuation\">.<\/span><span class=\"token function\">trim_start<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">starts_with<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;&#096;&#096;&#096;&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                in_code_block <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">!<\/span>in_code_block<span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token keyword\">if<\/span> current<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#043;<\/span> line<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token number\">1<\/span> <span class=\"token operator\">&gt;<\/span> max_len <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">if<\/span> <span class=\"token operator\">!<\/span>current<span class=\"token punctuation\">.<\/span><span class=\"token function\">is_empty<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    chunks<span class=\"token punctuation\">.<\/span><span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span>current<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    current<span class=\"token punctuation\">.<\/span><span class=\"token function\">clear<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><\/p>\n<p>                <span class=\"token comment\">\/\/ \u5982\u679c\u5f53\u524d\u5728\u4ee3\u7801\u5757\u4e2d&#xff0c;\u6dfb\u52a0\u4ee3\u7801\u5757\u6807\u8bb0<\/span><br \/>\n                <span class=\"token keyword\">if<\/span> in_code_block <span class=\"token punctuation\">{<\/span><br \/>\n                    current<span class=\"token punctuation\">.<\/span><span class=\"token function\">push_str<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;&#096;&#096;&#096;\\\\n&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            current<span class=\"token punctuation\">.<\/span><span class=\"token function\">push_str<\/span><span class=\"token punctuation\">(<\/span>line<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            current<span class=\"token punctuation\">.<\/span><span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span><span class=\"token char\">&#039;\\\\n&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token operator\">!<\/span>current<span class=\"token punctuation\">.<\/span><span class=\"token function\">is_empty<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            chunks<span class=\"token punctuation\">.<\/span><span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span>current<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        chunks<br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h3>3.4 \u56de\u8c03\u673a\u5236\u4e0e\u5f02\u6b65\u6d88\u606f\u5904\u7406<\/h3>\n<h4>3.4.1 \u56de\u8c03\u67b6\u6784\u603b\u89c8<\/h4>\n<p>\u8bb8\u591a\u5373\u65f6\u901a\u8baf\u5e73\u53f0\u91c7\u7528 Webhook \u56de\u8c03\u673a\u5236\u63a8\u9001\u6d88\u606f&#xff0c;\u8fd9\u662f\u4e00\u79cd\u5f02\u6b65\u3001\u88ab\u52a8\u7684\u6d88\u606f\u63a5\u6536\u6a21\u5f0f\u3002Gateway \u9700\u8981\u5904\u7406\u56de\u8c03\u6d88\u606f\u7684\u63a5\u6536\u3001\u9a8c\u8bc1\u3001\u53bb\u91cd\u548c\u6709\u5e8f\u5904\u7406&#xff1a;<\/p>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502                    Webhook \u56de\u8c03\u5904\u7406\u67b6\u6784                                 \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510     HTTPS POST     \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                    \u2502<br \/>\n\u2502  \u2502 \u98de\u4e66\u5e73\u53f0   \u2502 \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550&gt; \u2502              \u2502                    \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                   \u2502  Webhook     \u2502                    \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                   \u2502  Receiver    \u2502                    \u2502<br \/>\n\u2502  \u2502 \u9489\u9489\u5e73\u53f0   \u2502 \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550&gt; \u2502              \u2502                    \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                    \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                          \u2502                             \u2502<br \/>\n\u2502  | \u4f01\u5fae\u5e73\u53f0  | \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550&gt;         \u2502                             \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                          v                             \u2502<br \/>\n\u2502                                  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                    \u2502<br \/>\n\u2502                                  \u2502  Signature   \u2502                    \u2502<br \/>\n\u2502                                  \u2502  Verifier    \u2502                    \u2502<br \/>\n\u2502                                  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                    \u2502<br \/>\n\u2502                                         \u2502                             \u2502<br \/>\n\u2502                                         v                             \u2502<br \/>\n\u2502                                  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                    \u2502<br \/>\n\u2502                                  \u2502  Dedup       \u2502                    \u2502<br \/>\n\u2502                                  \u2502  Cache       \u2502                    \u2502<br \/>\n\u2502                                  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                    \u2502<br \/>\n\u2502                                         \u2502                             \u2502<br \/>\n\u2502                                         v                             \u2502<br \/>\n\u2502                                  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                    \u2502<br \/>\n\u2502                                  \u2502  Message     \u2502                    \u2502<br \/>\n\u2502                                  \u2502  Queue       \u2502 (Kafka)            \u2502<br \/>\n\u2502                                  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                    \u2502<br \/>\n\u2502                                         \u2502                             \u2502<br \/>\n\u2502                          \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510             \u2502<br \/>\n\u2502                          \u2502              \u2502              \u2502             \u2502<br \/>\n\u2502                          v              v              v             \u2502<br \/>\n\u2502                    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510         \u2502<br \/>\n\u2502                    \u2502 Worker 1 \u2502  \u2502 Worker 2 \u2502  \u2502 Worker N \u2502         \u2502<br \/>\n\u2502                    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518         \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<h4>3.4.2 \u56de\u8c03\u5904\u7406\u5b9e\u73b0<\/h4>\n<p><span class=\"token comment\">\/\/\/ Webhook \u56de\u8c03\u5904\u7406\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">WebhookHandler<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6e20\u9053\u9002\u914d\u5668\u6ce8\u518c\u8868<\/span><br \/>\n    adapters<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">AdapterRegistry<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6d88\u606f\u53bb\u91cd\u7f13\u5b58<\/span><br \/>\n    dedup_cache<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">DedupCache<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6d88\u606f\u961f\u5217<\/span><br \/>\n    message_queue<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">MessageQueue<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7b7e\u540d\u9a8c\u8bc1\u5668<\/span><br \/>\n    signature_verifier<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SignatureVerifier<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">WebhookHandler<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5904\u7406 Webhook \u56de\u8c03<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">handle_callback<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        channel<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        headers<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">HeaderMap<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        body<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Bytes<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">CallbackResponse<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">CallbackError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ 1. \u83b7\u53d6\u6e20\u9053\u9002\u914d\u5668<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> adapter <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>adapters<span class=\"token punctuation\">.<\/span><span class=\"token function\">get_or_create<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>channel<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 2. \u6784\u9020\u539f\u59cb\u6d88\u606f<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> raw <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">RawMessage<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            source<span class=\"token punctuation\">:<\/span> channel<span class=\"token punctuation\">,<\/span><br \/>\n            headers<span class=\"token punctuation\">:<\/span> headers<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            body<span class=\"token punctuation\">:<\/span> body<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            id<span class=\"token punctuation\">:<\/span> headers<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;x-request-id&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">and_then<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>v<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> v<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_str<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            timestamp<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Utc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            text_preview<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 3. \u9a8c\u8bc1\u6d88\u606f\u7b7e\u540d<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> verified <span class=\"token operator\">&#061;<\/span> adapter<span class=\"token punctuation\">.<\/span><span class=\"token function\">verify_message<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>raw<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token operator\">!<\/span>verified <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Err<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CallbackError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">SignatureVerificationFailed<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 4. \u6d88\u606f\u53bb\u91cd&#xff08;\u57fa\u4e8e\u6d88\u606fID&#xff09;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> message_key <span class=\"token operator\">&#061;<\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;{}:{}&#034;<\/span><span class=\"token punctuation\">,<\/span> channel<span class=\"token punctuation\">,<\/span> raw<span class=\"token punctuation\">.<\/span>id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>dedup_cache<span class=\"token punctuation\">.<\/span><span class=\"token function\">exists<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>message_key<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token namespace\">tracing<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">warn!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                channel <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">?<\/span>channel<span class=\"token punctuation\">,<\/span><br \/>\n                message_id <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">%<\/span>raw<span class=\"token punctuation\">.<\/span>id<span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;Duplicate callback detected, skipping&#034;<\/span><br \/>\n            <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CallbackResponse<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Duplicate<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 5. \u7acb\u5373\u8fd4\u56de 200 ACK&#xff08;\u4e0d\u7b49\u5904\u7406\u5b8c\u6210&#xff09;<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u6d88\u606f\u5f02\u6b65\u5904\u7406<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 6. \u5c06\u6d88\u606f\u6295\u5165\u961f\u5217\u5f02\u6b65\u5904\u7406<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>message_queue<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">enqueue<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">MessageQueueItem<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                channel<span class=\"token punctuation\">,<\/span><br \/>\n                raw_message<span class=\"token punctuation\">:<\/span> raw<span class=\"token punctuation\">,<\/span><br \/>\n                enqueued_at<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Utc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 7. \u6807\u8bb0\u53bb\u91cd<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>dedup_cache<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">set<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>message_key<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;1&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">from_secs<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">300<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CallbackResponse<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Accepted<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u5f02\u6b65\u6d88\u606f\u6d88\u8d39\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">AsyncMessageConsumer<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    adapters<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">AdapterRegistry<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    pipeline<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">NormalizationPipeline<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    session_manager<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SessionIsolationManager<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    routing_engine<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RoutingEngine<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">AsyncMessageConsumer<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6d88\u8d39\u961f\u5217\u4e2d\u7684\u6d88\u606f<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">consume<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> item<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">MessageQueueItem<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> result <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">process_message<\/span><span class=\"token punctuation\">(<\/span>item<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Err<\/span><span class=\"token punctuation\">(<\/span>e<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> result <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token namespace\">tracing<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">error!<\/span><span class=\"token punctuation\">(<\/span>error <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">%<\/span>e<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Message processing failed&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token comment\">\/\/ TODO: \u91cd\u8bd5\u903b\u8f91\u6216\u6b7b\u4fe1\u961f\u5217<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">process_message<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        item<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">MessageQueueItem<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">ProcessingError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ 1. \u83b7\u53d6\u9002\u914d\u5668<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> adapter <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>adapters<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">get_or_create<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>item<span class=\"token punctuation\">.<\/span>channel<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 2. \u901a\u8fc7\u5f52\u4e00\u5316\u7ba1\u7ebf\u5904\u7406<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> inbound <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>pipeline<span class=\"token punctuation\">.<\/span><span class=\"token function\">execute<\/span><span class=\"token punctuation\">(<\/span>item<span class=\"token punctuation\">.<\/span>raw_message<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 3. \u83b7\u53d6\u6216\u521b\u5efa\u4f1a\u8bdd<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> session_id <span class=\"token operator\">&#061;<\/span> inbound<span class=\"token punctuation\">.<\/span>metadata<span class=\"token punctuation\">.<\/span>session_id<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">ok_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ProcessingError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">MissingSessionId<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 4. \u52a0\u8f7d\u4f1a\u8bdd\u4e0a\u4e0b\u6587<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> context <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>session_manager<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">get_context<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>session_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 5. \u5c06\u7528\u6237\u6d88\u606f\u8ffd\u52a0\u5230\u4e0a\u4e0b\u6587<\/span><br \/>\n        context<span class=\"token punctuation\">.<\/span>messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Message<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            message_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">MessageId<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            role<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">MessageRole<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">User<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            content<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">MessageContent<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Text<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                inbound<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">.<\/span>text<span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or_default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            timestamp<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Utc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            metadata<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">MessageMetadata<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            tool_calls<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            status<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">MessageStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Sent<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 6. \u8def\u7531\u5230\u6838\u5fc3\u5904\u7406\u5f15\u64ce<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> response <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>routing_engine<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">process<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>session_id<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">mut<\/span> context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 7. \u901a\u8fc7\u9002\u914d\u5668\u53d1\u9001\u54cd\u5e94<\/span><br \/>\n        adapter<span class=\"token punctuation\">.<\/span><span class=\"token function\">send_message<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">OutboundMessage<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            target<span class=\"token punctuation\">:<\/span> inbound<span class=\"token punctuation\">.<\/span>metadata<span class=\"token punctuation\">.<\/span>chat_id<span class=\"token punctuation\">,<\/span><br \/>\n            content<span class=\"token punctuation\">:<\/span> response<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">,<\/span><br \/>\n            render_hint<span class=\"token punctuation\">:<\/span> response<span class=\"token punctuation\">.<\/span>render_hint<span class=\"token punctuation\">,<\/span><br \/>\n            streaming<span class=\"token punctuation\">:<\/span> response<span class=\"token punctuation\">.<\/span>streaming<span class=\"token punctuation\">,<\/span><br \/>\n            message_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>3.4.3 \u6d88\u606f\u6709\u5e8f\u6027\u4fdd\u8bc1<\/h4>\n<p>\u5728\u5f02\u6b65\u5904\u7406\u67b6\u6784\u4e0b&#xff0c;\u4fdd\u8bc1\u540c\u4e00\u4f1a\u8bdd\u5185\u6d88\u606f\u7684\u6709\u5e8f\u5904\u7406\u662f\u4e00\u4e2a\u5173\u952e\u6311\u6218\u3002Gateway \u901a\u8fc7\u4f1a\u8bdd\u7ea7\u9501\u548c\u5206\u533a\u6709\u5e8f\u961f\u5217\u5b9e\u73b0\u6d88\u606f\u6709\u5e8f\u6027&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u4f1a\u8bdd\u7ea7\u6709\u5e8f\u5904\u7406\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">OrderedSessionProcessor<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4f1a\u8bdd\u9501&#xff08;\u786e\u4fdd\u540c\u4e00\u4f1a\u8bdd\u7684\u6d88\u606f\u4e32\u884c\u5904\u7406&#xff09;<\/span><br \/>\n    session_locks<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">DashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token namespace\">tokio<span class=\"token punctuation\">::<\/span>sync<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Mutex<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5904\u7406\u5668<\/span><br \/>\n    processor<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">AsyncMessageConsumer<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">OrderedSessionProcessor<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">process_ordered<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        session_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        item<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">MessageQueueItem<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">ProcessingError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u83b7\u53d6\u4f1a\u8bdd\u7ea7\u9501<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> lock <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>session_locks<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">entry<\/span><span class=\"token punctuation\">(<\/span>session_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">or_insert_with<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span><span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token namespace\">tokio<span class=\"token punctuation\">::<\/span>sync<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Mutex<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> _guard <span class=\"token operator\">&#061;<\/span> lock<span class=\"token punctuation\">.<\/span><span class=\"token function\">lock<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u4e32\u884c\u5904\u7406\u540c\u4e00\u4f1a\u8bdd\u7684\u6d88\u606f<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>processor<span class=\"token punctuation\">.<\/span><span class=\"token function\">process_message<\/span><span class=\"token punctuation\">(<\/span>item<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u6709\u5e8f\u6027\u4fdd\u8bc1\u7684\u7b56\u7565\u5206\u5c42&#xff1a;<\/p>\n<table>\n<tr>\u5c42\u7ea7\u7b56\u7565\u4fdd\u8bc1\u8303\u56f4\u6027\u80fd\u5f71\u54cd<\/tr>\n<tbody>\n<tr>\n<td>\u961f\u5217\u5c42<\/td>\n<td>\u6309\u4f1a\u8bddID\u5206\u533a<\/td>\n<td>\u540c\u4e00\u4f1a\u8bdd\u6d88\u606f\u8fdb\u5165\u540c\u4e00\u5206\u533a<\/td>\n<td>\u65e0\u989d\u5916\u5f00\u9500<\/td>\n<\/tr>\n<tr>\n<td>\u6d88\u8d39\u5c42<\/td>\n<td>\u4f1a\u8bdd\u7ea7\u4e92\u65a5\u9501<\/td>\n<td>\u540c\u4e00\u4f1a\u8bdd\u6d88\u606f\u4e32\u884c\u5904\u7406<\/td>\n<td>\u9501\u7b49\u5f85 &lt;1ms<\/td>\n<\/tr>\n<tr>\n<td>\u5e94\u7528\u5c42<\/td>\n<td>\u4e50\u89c2\u5e76\u53d1\u63a7\u5236<\/td>\n<td>\u68c0\u6d4b\u5e76\u53d1\u4fee\u6539\u5e76\u91cd\u8bd5<\/td>\n<td>\u51b2\u7a81\u7387 &lt;0.1%<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>3.5 \u6e20\u9053\u5065\u5eb7\u68c0\u67e5\u4e0e\u6545\u969c\u8f6c\u79fb<\/h3>\n<h4>3.5.1 \u5065\u5eb7\u68c0\u67e5\u673a\u5236<\/h4>\n<p>Gateway \u5bf9\u6bcf\u4e2a\u6e20\u9053\u9002\u914d\u5668\u5b9e\u65bd\u6301\u7eed\u7684\u5065\u5eb7\u76d1\u6d4b&#xff0c;\u53ca\u65f6\u53d1\u73b0\u6e20\u9053\u6545\u969c\u5e76\u89e6\u53d1\u8f6c\u79fb&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u6e20\u9053\u5065\u5eb7\u68c0\u67e5\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ChannelHealthChecker<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5065\u5eb7\u72b6\u6001\u7f13\u5b58<\/span><br \/>\n    health_status<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">HealthState<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u68c0\u67e5\u95f4\u9694<\/span><br \/>\n    check_interval<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4e0d\u5065\u5eb7\u9608\u503c&#xff08;\u8fde\u7eed\u5931\u8d25\u6b21\u6570&#xff09;<\/span><br \/>\n    unhealthy_threshold<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u32<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6062\u590d\u9608\u503c&#xff08;\u8fde\u7eed\u6210\u529f\u6b21\u6570&#xff09;<\/span><br \/>\n    healthy_threshold<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u32<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">HealthState<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> status<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">HealthStatus<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> consecutive_failures<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u32<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> consecutive_successes<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u32<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> last_check_at<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">DateTime<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> last_failure_reason<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> latency_history<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">VecDeque<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Duration<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug, PartialEq, Eq)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">HealthStatus<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Healthy<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">Degraded<\/span> <span class=\"token punctuation\">{<\/span> success_rate<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">f64<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">Unhealthy<\/span> <span class=\"token punctuation\">{<\/span> since<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">DateTime<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">ChannelHealthChecker<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u542f\u52a8\u6301\u7eed\u5065\u5eb7\u68c0\u67e5<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">run_checks<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> adapters<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">AdapterRegistry<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> interval <span class=\"token operator\">&#061;<\/span> <span class=\"token namespace\">tokio<span class=\"token punctuation\">::<\/span>time<span class=\"token punctuation\">::<\/span><\/span><span class=\"token function\">interval<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>check_interval<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">loop<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            interval<span class=\"token punctuation\">.<\/span><span class=\"token function\">tick<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token keyword\">let<\/span> channels <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get_all_channels<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token keyword\">for<\/span> channel <span class=\"token keyword\">in<\/span> channels <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">let<\/span> adapter <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">match<\/span> adapters<span class=\"token punctuation\">.<\/span><span class=\"token function\">get_or_create<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>channel<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>a<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> a<span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token class-name\">Err<\/span><span class=\"token punctuation\">(<\/span>_<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">continue<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>                <span class=\"token keyword\">let<\/span> check_result <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">check_single<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>channel<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span>adapter<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">update_health_status<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>channel<span class=\"token punctuation\">,<\/span> check_result<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">check_single<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        channel<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        adapter<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">dyn<\/span> <span class=\"token class-name\">ChannelAdapter<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">CheckResult<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> start <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Instant<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">match<\/span> adapter<span class=\"token punctuation\">.<\/span><span class=\"token function\">health_check<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">HealthStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Healthy<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token class-name\">CheckResult<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                success<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                latency<span class=\"token punctuation\">:<\/span> start<span class=\"token punctuation\">.<\/span><span class=\"token function\">elapsed<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                reason<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">HealthStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Unhealthy<\/span> <span class=\"token punctuation\">{<\/span> reason<span class=\"token punctuation\">,<\/span> since <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token class-name\">CheckResult<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                success<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                latency<span class=\"token punctuation\">:<\/span> start<span class=\"token punctuation\">.<\/span><span class=\"token function\">elapsed<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                reason<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Unhealthy since {}: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> since<span class=\"token punctuation\">,<\/span> reason<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">Err<\/span><span class=\"token punctuation\">(<\/span>e<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token class-name\">CheckResult<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                success<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                latency<span class=\"token punctuation\">:<\/span> start<span class=\"token punctuation\">.<\/span><span class=\"token function\">elapsed<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                reason<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>e<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">update_health_status<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        channel<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        result<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">CheckResult<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> states <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>health_status<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> state <span class=\"token operator\">&#061;<\/span> states<span class=\"token punctuation\">.<\/span><span class=\"token function\">entry<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">*<\/span>channel<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">or_insert<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">HealthState<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            status<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">HealthStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Healthy<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            consecutive_failures<span class=\"token punctuation\">:<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            consecutive_successes<span class=\"token punctuation\">:<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            last_check_at<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Utc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            last_failure_reason<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            latency_history<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">VecDeque<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">with_capacity<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">100<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8bb0\u5f55\u5ef6\u8fdf<\/span><br \/>\n        state<span class=\"token punctuation\">.<\/span>latency_history<span class=\"token punctuation\">.<\/span><span class=\"token function\">push_back<\/span><span class=\"token punctuation\">(<\/span>result<span class=\"token punctuation\">.<\/span>latency<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> state<span class=\"token punctuation\">.<\/span>latency_history<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;<\/span> <span class=\"token number\">100<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            state<span class=\"token punctuation\">.<\/span>latency_history<span class=\"token punctuation\">.<\/span><span class=\"token function\">pop_front<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        state<span class=\"token punctuation\">.<\/span>last_check_at <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Utc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> result<span class=\"token punctuation\">.<\/span>success <span class=\"token punctuation\">{<\/span><br \/>\n            state<span class=\"token punctuation\">.<\/span>consecutive_successes <span class=\"token operator\">&#043;&#061;<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            state<span class=\"token punctuation\">.<\/span>consecutive_failures <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u6062\u590d\u5224\u5b9a<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> state<span class=\"token punctuation\">.<\/span>consecutive_successes <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>healthy_threshold <span class=\"token punctuation\">{<\/span><br \/>\n                state<span class=\"token punctuation\">.<\/span>status <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">HealthStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Healthy<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            state<span class=\"token punctuation\">.<\/span>consecutive_failures <span class=\"token operator\">&#043;&#061;<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            state<span class=\"token punctuation\">.<\/span>consecutive_successes <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            state<span class=\"token punctuation\">.<\/span>last_failure_reason <span class=\"token operator\">&#061;<\/span> result<span class=\"token punctuation\">.<\/span>reason<span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u6545\u969c\u5224\u5b9a<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> state<span class=\"token punctuation\">.<\/span>consecutive_failures <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>unhealthy_threshold <span class=\"token punctuation\">{<\/span><br \/>\n                state<span class=\"token punctuation\">.<\/span>status <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">HealthStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Unhealthy<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    since<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Utc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>                <span class=\"token namespace\">tracing<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">error!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    channel <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">?<\/span>channel<span class=\"token punctuation\">,<\/span><br \/>\n                    reason <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">?<\/span>result<span class=\"token punctuation\">.<\/span>reason<span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token string\">&#034;Channel marked as unhealthy&#034;<\/span><br \/>\n                <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>                <span class=\"token comment\">\/\/ \u89e6\u53d1\u6545\u969c\u8f6c\u79fb<\/span><br \/>\n                <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">trigger_failover<\/span><span class=\"token punctuation\">(<\/span>channel<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u89e6\u53d1\u6e20\u9053\u6545\u969c\u8f6c\u79fb<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">trigger_failover<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> channel<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">ChannelType<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ 1. \u901a\u77e5\u6240\u6709\u6b63\u5728\u4f7f\u7528\u8be5\u6e20\u9053\u7684\u4f1a\u8bdd<\/span><br \/>\n        <span class=\"token comment\">\/\/ 2. \u5c06\u5f85\u53d1\u9001\u6d88\u606f\u8f6c\u79fb\u5230\u5907\u7528\u6e20\u9053\u6216\u961f\u5217<\/span><br \/>\n        <span class=\"token comment\">\/\/ 3. \u53d1\u9001\u544a\u8b66\u901a\u77e5<\/span><br \/>\n        <span class=\"token namespace\">tracing<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">warn!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            channel <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">?<\/span>channel<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;Initiating channel failover&#034;<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>3.5.2 \u6545\u969c\u8f6c\u79fb\u7b56\u7565<\/h4>\n<p>\u5f53\u6e20\u9053\u4e0d\u53ef\u7528\u65f6&#xff0c;Gateway \u6839\u636e\u914d\u7f6e\u7684\u6545\u969c\u8f6c\u79fb\u7b56\u7565\u5904\u7406\u5f85\u53d1\u9001\u6d88\u606f&#xff1a;<\/p>\n<table>\n<tr>\u7b56\u7565\u63cf\u8ff0\u9002\u7528\u573a\u666f\u7528\u6237\u4f53\u9a8c<\/tr>\n<tbody>\n<tr>\n<td>queue<\/td>\n<td>\u6d88\u606f\u6682\u5b58\u961f\u5217&#xff0c;\u6e20\u9053\u6062\u590d\u540e\u53d1\u9001<\/td>\n<td>\u77ed\u6682\u6545\u969c&#xff08;&lt;5\u5206\u949f&#xff09;<\/td>\n<td>\u5ef6\u8fdf\u63a5\u6536<\/td>\n<\/tr>\n<tr>\n<td>fallback_channel<\/td>\n<td>\u8f6c\u79fb\u5230\u5907\u7528\u6e20\u9053\u53d1\u9001<\/td>\n<td>\u6709\u660e\u786e\u5907\u7528\u6e20\u9053<\/td>\n<td>\u6536\u5230\u6765\u81ea\u4e0d\u540c\u6e20\u9053\u7684\u6d88\u606f<\/td>\n<\/tr>\n<tr>\n<td>notify<\/td>\n<td>\u901a\u77e5\u7528\u6237\u6e20\u9053\u4e0d\u53ef\u7528<\/td>\n<td>\u957f\u65f6\u95f4\u6545\u969c<\/td>\n<td>\u6536\u5230\u6545\u969c\u901a\u77e5<\/td>\n<\/tr>\n<tr>\n<td>discard<\/td>\n<td>\u4e22\u5f03\u975e\u5173\u952e\u6d88\u606f<\/td>\n<td>\u5b9e\u65f6\u6027\u8981\u6c42\u4f4e\u7684\u573a\u666f<\/td>\n<td>\u65e0\u611f\u77e5<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span class=\"token comment\"># \u6545\u969c\u8f6c\u79fb\u914d\u7f6e\u793a\u4f8b<\/span><br \/>\n<span class=\"token key atrule\">failover<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token key atrule\">feishu<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">strategy<\/span><span class=\"token punctuation\">:<\/span> queue<br \/>\n    <span class=\"token key atrule\">max_queue_size<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1000<\/span><br \/>\n    <span class=\"token key atrule\">queue_timeout<\/span><span class=\"token punctuation\">:<\/span> 300s<br \/>\n    <span class=\"token key atrule\">fallback_channel<\/span><span class=\"token punctuation\">:<\/span> web<br \/>\n    <span class=\"token key atrule\">notify_after<\/span><span class=\"token punctuation\">:<\/span> 60s<\/p>\n<p>  <span class=\"token key atrule\">dingtalk<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">strategy<\/span><span class=\"token punctuation\">:<\/span> fallback_channel<br \/>\n    <span class=\"token key atrule\">fallback_channel<\/span><span class=\"token punctuation\">:<\/span> feishu<\/p>\n<p>  <span class=\"token key atrule\">web<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">strategy<\/span><span class=\"token punctuation\">:<\/span> queue<br \/>\n    <span class=\"token key atrule\">max_queue_size<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">5000<\/span><br \/>\n    <span class=\"token key atrule\">queue_timeout<\/span><span class=\"token punctuation\">:<\/span> 600s<\/p>\n<p>  <span class=\"token key atrule\">email<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">strategy<\/span><span class=\"token punctuation\">:<\/span> discard<br \/>\n    <span class=\"token key atrule\">discard_after<\/span><span class=\"token punctuation\">:<\/span> 300s<\/p>\n<hr \/>\n<h2>\u7b2c\u56db\u7ae0 \u5de5\u5177\u6ce8\u518c\u8868\u8bbe\u8ba1<\/h2>\n<p>\u5de5\u5177\u6ce8\u518c\u8868\u662f Gateway \u4e2d\u7ba1\u7406 Agent \u53ef\u7528\u5de5\u5177\u7684\u6838\u5fc3\u7ec4\u4ef6\u3002\u5b83\u8d1f\u8d23\u5de5\u5177\u7684\u6ce8\u518c\u3001\u53d1\u73b0\u3001\u7248\u672c\u7ba1\u7406\u3001\u6743\u9650\u63a7\u5236\u548c\u8c03\u7528\u5ba1\u8ba1&#xff0c;\u662f Agent \u80fd\u529b\u6269\u5c55\u7684\u57fa\u7840\u8bbe\u65bd\u3002<\/p>\n<h3>4.1 \u5de5\u5177\u6ce8\u518c\u4e0e\u53d1\u73b0\u673a\u5236<\/h3>\n<h4>4.1.1 \u5de5\u5177\u5143\u6570\u636e\u6a21\u578b<\/h4>\n<p>\u6bcf\u4e2a\u5de5\u5177\u5728\u6ce8\u518c\u8868\u4e2d\u90fd\u6709\u4e00\u4efd\u5b8c\u6574\u7684\u5143\u6570\u636e\u63cf\u8ff0&#xff0c;\u5b9a\u4e49\u4e86\u5de5\u5177\u7684\u8eab\u4efd\u3001\u80fd\u529b\u3001\u63a5\u53e3\u548c\u7ea6\u675f&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u5de5\u5177\u5143\u6570\u636e<\/span><br \/>\n<span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ToolDescriptor<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5de5\u5177\u552f\u4e00\u6807\u8bc6<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> tool_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ToolId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5de5\u5177\u540d\u79f0&#xff08;\u4eba\u7c7b\u53ef\u8bfb&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> name<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5de5\u5177\u63cf\u8ff0&#xff08;\u4f9bLLM\u7406\u89e3\u5de5\u5177\u7528\u9014&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> description<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5de5\u5177\u7248\u672c<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> version<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">SemVer<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5de5\u5177\u7c7b\u522b<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> category<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ToolCategory<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5de5\u5177\u63d0\u4f9b\u8005<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> provider<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ToolProvider<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u8f93\u5165\u53c2\u6570Schema (JSON Schema)<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> input_schema<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u8f93\u51fa\u683c\u5f0fSchema<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> output_schema<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6267\u884c\u8d85\u65f6<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> timeout<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u662f\u5426\u9700\u8981\u6c99\u7bb1<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> requires_sandbox<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6240\u9700\u6743\u9650<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> required_permissions<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Permission<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u901f\u7387\u9650\u5236<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> rate_limit<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RateLimit<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5de5\u5177\u72b6\u6001<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> status<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ToolStatus<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6807\u7b7e<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> tags<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4f7f\u7528\u7edf\u8ba1<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> stats<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ToolStats<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">ToolCategory<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4ee3\u7801\u6267\u884c<\/span><br \/>\n    <span class=\"token class-name\">CodeExecution<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7f51\u7edc\u8bf7\u6c42<\/span><br \/>\n    <span class=\"token class-name\">HttpRequest<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6587\u4ef6\u64cd\u4f5c<\/span><br \/>\n    <span class=\"token class-name\">FileOperation<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6570\u636e\u5e93\u64cd\u4f5c<\/span><br \/>\n    <span class=\"token class-name\">Database<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u641c\u7d22\u68c0\u7d22<\/span><br \/>\n    <span class=\"token class-name\">Search<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u77e5\u8bc6\u5e93\u67e5\u8be2<\/span><br \/>\n    <span class=\"token class-name\">KnowledgeQuery<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u56fe\u50cf\u5904\u7406<\/span><br \/>\n    <span class=\"token class-name\">ImageProcessing<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6570\u636e\u5206\u6790<\/span><br \/>\n    <span class=\"token class-name\">DataAnalysis<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5916\u90e8API<\/span><br \/>\n    <span class=\"token class-name\">ExternalApi<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ MCP\u5de5\u5177<\/span><br \/>\n    <span class=\"token class-name\">McpTool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u81ea\u5b9a\u4e49<\/span><br \/>\n    <span class=\"token class-name\">Custom<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ToolStats<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u603b\u8c03\u7528\u6b21\u6570<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> total_calls<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6210\u529f\u6b21\u6570<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> successful_calls<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5931\u8d25\u6b21\u6570<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> failed_calls<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5e73\u5747\u5ef6\u8fdf&#xff08;\u6beb\u79d2&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> avg_latency_ms<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">f64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ P99\u5ef6\u8fdf&#xff08;\u6beb\u79d2&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> p99_latency_ms<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">f64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6700\u540e\u8c03\u7528\u65f6\u95f4<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> last_called_at<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">DateTime<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ JSON Schema \u793a\u4f8b&#xff1a;HTTP\u8bf7\u6c42\u5de5\u5177\u7684\u8f93\u5165\u5b9a\u4e49<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">http_request_tool_schema<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token string\">&#034;type&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;object&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token string\">&#034;properties&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token string\">&#034;method&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token string\">&#034;type&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;string&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;enum&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;GET&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;POST&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;PUT&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;DELETE&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;PATCH&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;HTTP method&#034;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;url&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token string\">&#034;type&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;string&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;format&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;uri&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;Request URL&#034;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;headers&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token string\">&#034;type&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;object&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;Request headers&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;additionalProperties&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token string\">&#034;type&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;string&#034;<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;body&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token string\">&#034;type&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;string&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;Request body (JSON string)&#034;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;timeout&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token string\">&#034;type&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;integer&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;minimum&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;maximum&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">120<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;default&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">30<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;Timeout in seconds&#034;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token string\">&#034;required&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;method&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;url&#034;<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>4.1.2 \u5de5\u5177\u6ce8\u518c\u8868\u5b9e\u73b0<\/h4>\n<p><span class=\"token comment\">\/\/\/ \u5de5\u5177\u6ce8\u518c\u8868<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ToolRegistry<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5df2\u6ce8\u518c\u5de5\u5177&#xff1a;ToolId -&gt; ToolDescriptor<\/span><br \/>\n    tools<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolId<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">ToolDescriptor<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5de5\u5177\u6267\u884c\u5668&#xff1a;ToolId -&gt; Box&lt;dyn ToolExecutor&gt;<\/span><br \/>\n    executors<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolId<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">dyn<\/span> <span class=\"token class-name\">ToolExecutor<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u540d\u79f0\u7d22\u5f15&#xff1a;name -&gt; Set&lt;ToolId&gt;&#xff08;\u652f\u6301\u540c\u540d\u4e0d\u540c\u7248\u672c&#xff09;<\/span><br \/>\n    name_index<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">HashSet<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolId<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6807\u7b7e\u7d22\u5f15&#xff1a;tag -&gt; Set&lt;ToolId&gt;<\/span><br \/>\n    tag_index<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">HashSet<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolId<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u914d\u7f6e\u4e2d\u5fc3&#xff08;\u76d1\u542c\u5de5\u5177\u914d\u7f6e\u53d8\u66f4&#xff09;<\/span><br \/>\n    config_source<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">dyn<\/span> <span class=\"token class-name\">ConfigSource<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[async_trait]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">trait<\/span> <span class=\"token type-definition class-name\">ToolExecutor<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Send<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token class-name\">Sync<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6267\u884c\u5de5\u5177<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">execute<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        input<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        context<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">ExecutionContext<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolOutput<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">ToolError<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u5065\u5eb7\u68c0\u67e5<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">health_check<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">ToolError<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u5de5\u5177\u6267\u884c\u4e0a\u4e0b\u6587<\/span><br \/>\n<span class=\"token attribute attr-name\">#[derive(Clone, Debug)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ExecutionContext<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> session_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> user_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">UserId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> tool_call_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> sandbox_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> deadline<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Instant<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> permissions<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Permission<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u5de5\u5177\u8f93\u51fa<\/span><br \/>\n<span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ToolOutput<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> success<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> result<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> error<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolErrorInfo<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> metadata<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">OutputMetadata<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">ToolRegistry<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6ce8\u518c\u65b0\u5de5\u5177<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">register<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        descriptor<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ToolDescriptor<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        executor<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">dyn<\/span> <span class=\"token class-name\">ToolExecutor<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">RegistryError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> tool_id <span class=\"token operator\">&#061;<\/span> descriptor<span class=\"token punctuation\">.<\/span>tool_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> name <span class=\"token operator\">&#061;<\/span> descriptor<span class=\"token punctuation\">.<\/span>name<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u9a8c\u8bc1\u5de5\u5177\u63cf\u8ff0\u7b26<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">validate_descriptor<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>descriptor<span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u6ce8\u518c\u5de5\u5177\u63cf\u8ff0\u7b26<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> tools <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>tools<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> tools<span class=\"token punctuation\">.<\/span><span class=\"token function\">contains_key<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>tool_id<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Err<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RegistryError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">ToolAlreadyExists<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n            tools<span class=\"token punctuation\">.<\/span><span class=\"token function\">insert<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> descriptor<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u6ce8\u518c\u6267\u884c\u5668<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> execs <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>executors<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            execs<span class=\"token punctuation\">.<\/span><span class=\"token function\">insert<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> executor<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u66f4\u65b0\u540d\u79f0\u7d22\u5f15<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> names <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>name_index<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            names<span class=\"token punctuation\">.<\/span><span class=\"token function\">entry<\/span><span class=\"token punctuation\">(<\/span>name<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">or_default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">insert<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u66f4\u65b0\u6807\u7b7e\u7d22\u5f15<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> tags <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>tag_index<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">for<\/span> tag <span class=\"token keyword\">in<\/span> <span class=\"token operator\">&amp;<\/span>descriptor<span class=\"token punctuation\">.<\/span>tags <span class=\"token punctuation\">{<\/span><br \/>\n                tags<span class=\"token punctuation\">.<\/span><span class=\"token function\">entry<\/span><span class=\"token punctuation\">(<\/span>tag<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">or_default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">insert<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token namespace\">tracing<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">info!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            tool_id <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">%<\/span>tool_id<span class=\"token punctuation\">,<\/span><br \/>\n            name <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">%<\/span>descriptor<span class=\"token punctuation\">.<\/span>name<span class=\"token punctuation\">,<\/span><br \/>\n            version <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">%<\/span>descriptor<span class=\"token punctuation\">.<\/span>version<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;Tool registered successfully&#034;<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u6ce8\u9500\u5de5\u5177<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">unregister<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> tool_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">ToolId<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">RegistryError<\/span><span class=\"token operator\">&gt;<\/span><br \/>\n    <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> descriptor <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> tools <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>tools<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            tools<span class=\"token punctuation\">.<\/span><span class=\"token function\">remove<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">ok_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RegistryError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">ToolNotFound<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u79fb\u9664\u6267\u884c\u5668<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> execs <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>executors<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            execs<span class=\"token punctuation\">.<\/span><span class=\"token function\">remove<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u66f4\u65b0\u540d\u79f0\u7d22\u5f15<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> names <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>name_index<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>ids<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> names<span class=\"token punctuation\">.<\/span><span class=\"token function\">get_mut<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>descriptor<span class=\"token punctuation\">.<\/span>name<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                ids<span class=\"token punctuation\">.<\/span><span class=\"token function\">remove<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token keyword\">if<\/span> ids<span class=\"token punctuation\">.<\/span><span class=\"token function\">is_empty<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    names<span class=\"token punctuation\">.<\/span><span class=\"token function\">remove<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>descriptor<span class=\"token punctuation\">.<\/span>name<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u66f4\u65b0\u6807\u7b7e\u7d22\u5f15<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> tags <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>tag_index<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">for<\/span> tag <span class=\"token keyword\">in<\/span> <span class=\"token operator\">&amp;<\/span>descriptor<span class=\"token punctuation\">.<\/span>tags <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>ids<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> tags<span class=\"token punctuation\">.<\/span><span class=\"token function\">get_mut<\/span><span class=\"token punctuation\">(<\/span>tag<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    ids<span class=\"token punctuation\">.<\/span><span class=\"token function\">remove<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    <span class=\"token keyword\">if<\/span> ids<span class=\"token punctuation\">.<\/span><span class=\"token function\">is_empty<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                        tags<span class=\"token punctuation\">.<\/span><span class=\"token function\">remove<\/span><span class=\"token punctuation\">(<\/span>tag<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token namespace\">tracing<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">info!<\/span><span class=\"token punctuation\">(<\/span>tool_id <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">%<\/span>tool_id<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Tool unregistered&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u5de5\u5177\u53d1\u73b0&#xff1a;\u6309\u540d\u79f0\u67e5\u627e&#xff08;\u8fd4\u56de\u6700\u65b0\u7248\u672c&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">find_by_name<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        name<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolDescriptor<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">RegistryError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> names <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>name_index<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> tool_ids <span class=\"token operator\">&#061;<\/span> names<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>name<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">ok_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RegistryError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">ToolNotFound<\/span><span class=\"token punctuation\">(<\/span>name<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> tools <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>tools<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> latest<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolDescriptor<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">for<\/span> id <span class=\"token keyword\">in<\/span> tool_ids <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>desc<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> tools<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>id<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">if<\/span> desc<span class=\"token punctuation\">.<\/span>status <span class=\"token operator\">!&#061;<\/span> <span class=\"token class-name\">ToolStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Disabled<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">match<\/span> <span class=\"token operator\">&amp;<\/span>latest <span class=\"token punctuation\">{<\/span><br \/>\n                        <span class=\"token class-name\">None<\/span> <span class=\"token operator\">&#061;&gt;<\/span> latest <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>desc<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>current<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">if<\/span> desc<span class=\"token punctuation\">.<\/span>version <span class=\"token operator\">&gt;<\/span> current<span class=\"token punctuation\">.<\/span>version <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                            latest <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>desc<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                        <span class=\"token punctuation\">}<\/span><br \/>\n                        _ <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        latest<span class=\"token punctuation\">.<\/span><span class=\"token function\">ok_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RegistryError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">ToolNotFound<\/span><span class=\"token punctuation\">(<\/span>name<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u5de5\u5177\u53d1\u73b0&#xff1a;\u6309\u6807\u7b7e\u67e5\u627e<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">find_by_tags<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        tags<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token punctuation\">[<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolDescriptor<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> tag_index <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>tag_index<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> tools <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>tools<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u53d6\u6240\u6709\u6807\u7b7e\u7684\u4ea4\u96c6<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> result_ids<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashSet<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolId<\/span><span class=\"token operator\">&gt;&gt;<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> tag <span class=\"token keyword\">in<\/span> tags <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>ids<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> tag_index<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>tag<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">match<\/span> <span class=\"token operator\">&amp;<\/span>result_ids <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token class-name\">None<\/span> <span class=\"token operator\">&#061;&gt;<\/span> result_ids <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>ids<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>current<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                        <span class=\"token keyword\">let<\/span> intersection<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">HashSet<\/span><span class=\"token operator\">&lt;<\/span>_<span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&#061;<\/span><br \/>\n                            current<span class=\"token punctuation\">.<\/span><span class=\"token function\">intersection<\/span><span class=\"token punctuation\">(<\/span>ids<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">cloned<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                        result_ids <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>intersection<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ \u6807\u7b7e\u4e0d\u5b58\u5728&#xff0c;\u65e0\u5339\u914d<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        result_ids<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or_default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">filter_map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>id<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> tools<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">cloned<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">filter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>d<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> d<span class=\"token punctuation\">.<\/span>status <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token class-name\">ToolStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Active<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u83b7\u53d6\u6240\u6709\u53ef\u7528\u5de5\u5177&#xff08;\u4f9bLLM\u4f5c\u4e3a\u5de5\u5177\u5217\u8868&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">list_available_tools<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        user_permissions<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token punctuation\">[<\/span><span class=\"token class-name\">Permission<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolSummary<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> tools <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>tools<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        tools<span class=\"token punctuation\">.<\/span><span class=\"token function\">values<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">filter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>d<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> d<span class=\"token punctuation\">.<\/span>status <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token class-name\">ToolStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Active<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">filter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>d<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token comment\">\/\/ \u68c0\u67e5\u7528\u6237\u662f\u5426\u6709\u8db3\u591f\u6743\u9650<\/span><br \/>\n                d<span class=\"token punctuation\">.<\/span>required_permissions<span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">all<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>p<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> user_permissions<span class=\"token punctuation\">.<\/span><span class=\"token function\">contains<\/span><span class=\"token punctuation\">(<\/span>p<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>d<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token class-name\">ToolSummary<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                name<span class=\"token punctuation\">:<\/span> d<span class=\"token punctuation\">.<\/span>name<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                description<span class=\"token punctuation\">:<\/span> d<span class=\"token punctuation\">.<\/span>description<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                input_schema<span class=\"token punctuation\">:<\/span> d<span class=\"token punctuation\">.<\/span>input_schema<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u5de5\u5177\u6458\u8981&#xff08;\u4f20\u9012\u7ed9LLM\u7684\u7cbe\u7b80\u683c\u5f0f&#xff09;<\/span><br \/>\n<span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ToolSummary<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> name<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> description<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> input_schema<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h3>4.2 MCP \u534f\u8bae\u96c6\u6210<\/h3>\n<h4>4.2.1 MCP \u534f\u8bae\u6982\u8ff0<\/h4>\n<p>MCP&#xff08;Model Context Protocol&#xff09;\u662f Anthropic \u63d0\u51fa\u7684\u5f00\u653e\u6807\u51c6\u534f\u8bae&#xff0c;\u65e8\u5728\u4e3a LLM \u63d0\u4f9b\u7edf\u4e00\u7684\u5de5\u5177\u3001\u8d44\u6e90\u548c\u63d0\u793a\u8bcd\u8bbf\u95ee\u63a5\u53e3\u3002Hermes Agent \u5c06 MCP \u4f5c\u4e3a\u5de5\u5177\u5c42\u7684\u4e00\u7b49\u516c\u6c11\u534f\u8bae&#xff0c;\u5b9e\u73b0\u4e86\u5b8c\u6574\u7684 MCP \u5ba2\u6237\u7aef\u96c6\u6210\u3002<\/p>\n<p>MCP \u7684\u6838\u5fc3\u6982\u5ff5&#xff1a;<\/p>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502                     MCP \u534f\u8bae\u67b6\u6784                                       \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510     MCP Protocol     \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510     \u2502<br \/>\n\u2502  \u2502              \u2502 &lt;\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550&gt; \u2502                      \u2502     \u2502<br \/>\n\u2502  \u2502  MCP Client  \u2502                      \u2502   MCP Server         \u2502     \u2502<br \/>\n\u2502  \u2502  (Gateway)   \u2502                      \u2502                      \u2502     \u2502<br \/>\n\u2502  \u2502              \u2502   \u00b7 tools\/list       \u2502  \u00b7 \u5de5\u5177\u5b9a\u4e49           \u2502     \u2502<br \/>\n\u2502  \u2502              \u2502   \u00b7 tools\/call       \u2502  \u00b7 \u5de5\u5177\u6267\u884c           \u2502     \u2502<br \/>\n\u2502  \u2502              \u2502   \u00b7 resources\/list   \u2502  \u00b7 \u8d44\u6e90\u66b4\u9732           \u2502     \u2502<br \/>\n\u2502  \u2502              \u2502   \u00b7 resources\/read   \u2502  \u00b7 \u8d44\u6e90\u8bfb\u53d6           \u2502     \u2502<br \/>\n\u2502  \u2502              \u2502   \u00b7 prompts\/list     \u2502  \u00b7 \u63d0\u793a\u8bcd\u6a21\u677f         \u2502     \u2502<br \/>\n\u2502  \u2502              \u2502   \u00b7 prompts\/get      \u2502  \u00b7 \u63d0\u793a\u8bcd\u751f\u6210         \u2502     \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                      \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518     \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u4f20\u8f93\u5c42: stdio | SSE | WebSocket | gRPC                              \u2502<br \/>\n\u2502  \u5e8f\u5217\u5316: JSON-RPC 2.0                                                \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<h4>4.2.2 MCP \u5ba2\u6237\u7aef\u5b9e\u73b0<\/h4>\n<p><span class=\"token comment\">\/\/\/ MCP \u5ba2\u6237\u7aef<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">McpClient<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4f20\u8f93\u5c42<\/span><br \/>\n    transport<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Box<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">dyn<\/span> <span class=\"token class-name\">McpTransport<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5df2\u53d1\u73b0\u7684\u5de5\u5177\u7f13\u5b58<\/span><br \/>\n    tools_cache<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">McpTool<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5df2\u53d1\u73b0\u7684\u8d44\u6e90\u7f13\u5b58<\/span><br \/>\n    resources_cache<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">McpResource<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u670d\u52a1\u5668\u80fd\u529b<\/span><br \/>\n    server_capabilities<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ServerCapabilities<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u8bf7\u6c42\u8d85\u65f6<\/span><br \/>\n    request_timeout<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[async_trait]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">trait<\/span> <span class=\"token type-definition class-name\">McpTransport<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Send<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token class-name\">Sync<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">send<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> message<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">JsonRpcRequest<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">TransportError<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">recv<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">JsonRpcResponse<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">TransportError<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">close<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">TransportError<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ stdio \u4f20\u8f93\u5b9e\u73b0<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">StdioTransport<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    process<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">tokio<span class=\"token punctuation\">::<\/span>process<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Child<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    stdin<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">tokio<span class=\"token punctuation\">::<\/span>process<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">ChildStdin<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    stdout<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">tokio<span class=\"token punctuation\">::<\/span>process<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">ChildStdout<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ SSE \u4f20\u8f93\u5b9e\u73b0<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">SseTransport<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    url<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    client<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">reqwest<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Client<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    event_source<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">EventSource<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">McpClient<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u8fde\u63a5 MCP \u670d\u52a1\u5668\u5e76\u521d\u59cb\u5316<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">connect<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        transport<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Box<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">dyn<\/span> <span class=\"token class-name\">McpTransport<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">Self<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">McpError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> client <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">McpClient<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            transport<span class=\"token punctuation\">,<\/span><br \/>\n            tools_cache<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            resources_cache<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            server_capabilities<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">None<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            request_timeout<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">from_secs<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">30<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u53d1\u9001 initialize \u8bf7\u6c42<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> init_response <span class=\"token operator\">&#061;<\/span> client<span class=\"token punctuation\">.<\/span><span class=\"token function\">send_request<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">JsonRpcRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            id<span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">into<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            method<span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;initialize&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            params<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token string\">&#034;protocolVersion&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;2024-11-05&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;capabilities&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token string\">&#034;roots&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token string\">&#034;listChanged&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token string\">&#034;sampling&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;clientInfo&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token string\">&#034;name&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;hermes-gateway&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token string\">&#034;version&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;1.0.0&#034;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u89e3\u6790\u670d\u52a1\u5668\u80fd\u529b<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> caps<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ServerCapabilities<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token function\">from_value<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            init_response<span class=\"token punctuation\">.<\/span>result<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;capabilities&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">cloned<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or_default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token operator\">*<\/span>client<span class=\"token punctuation\">.<\/span>server_capabilities<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>caps<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u53d1\u9001 initialized \u901a\u77e5<\/span><br \/>\n        client<span class=\"token punctuation\">.<\/span><span class=\"token function\">send_notification<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;notifications\/initialized&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>client<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u53d1\u73b0\u53ef\u7528\u5de5\u5177<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">list_tools<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">McpTool<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">McpError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> response <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">send_request<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">JsonRpcRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            id<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">next_id<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            method<span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;tools\/list&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            params<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> tools<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">McpTool<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token function\">from_value<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            response<span class=\"token punctuation\">.<\/span>result<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;tools&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">cloned<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or_default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u66f4\u65b0\u7f13\u5b58<\/span><br \/>\n        <span class=\"token operator\">*<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>tools_cache<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span> <span class=\"token operator\">&#061;<\/span> tools<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>tools<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u8c03\u7528\u5de5\u5177<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">call_tool<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        name<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        arguments<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">McpToolResult<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">McpError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> response <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">send_request<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">JsonRpcRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            id<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">next_id<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            method<span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;tools\/call&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            params<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token string\">&#034;name&#034;<\/span><span class=\"token punctuation\">:<\/span> name<span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;arguments&#034;<\/span><span class=\"token punctuation\">:<\/span> arguments<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> result<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">McpToolResult<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token function\">from_value<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            response<span class=\"token punctuation\">.<\/span>result<br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>result<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u8bfb\u53d6\u8d44\u6e90<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">read_resource<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        uri<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">McpResourceContent<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">McpError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> response <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">send_request<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">JsonRpcRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            id<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">next_id<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            method<span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;resources\/read&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            params<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token string\">&#034;uri&#034;<\/span><span class=\"token punctuation\">:<\/span> uri<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> content<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">McpResourceContent<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token function\">from_value<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            response<span class=\"token punctuation\">.<\/span>result<br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>content<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>4.2.3 MCP \u5de5\u5177\u5230 Gateway \u6ce8\u518c\u8868\u7684\u6620\u5c04<\/h4>\n<p>MCP \u670d\u52a1\u5668\u53d1\u73b0\u7684\u5de5\u5177\u9700\u8981\u81ea\u52a8\u6ce8\u518c\u5230 Gateway \u7684\u5de5\u5177\u6ce8\u518c\u8868\u4e2d&#xff0c;\u4f7f\u5f97\u6838\u5fc3\u8def\u7531\u5f15\u64ce\u53ef\u4ee5\u7edf\u4e00\u8c03\u5ea6&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ MCP \u5de5\u5177\u6ce8\u518c\u6865\u63a5\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">McpToolBridge<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ MCP \u5ba2\u6237\u7aef<\/span><br \/>\n    mcp_client<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">McpClient<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ Gateway \u5de5\u5177\u6ce8\u518c\u8868<\/span><br \/>\n    registry<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolRegistry<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u670d\u52a1\u5668\u6807\u8bc6<\/span><br \/>\n    server_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u81ea\u52a8\u540c\u6b65\u95f4\u9694<\/span><br \/>\n    sync_interval<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">McpToolBridge<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u542f\u52a8\u81ea\u52a8\u540c\u6b65&#xff1a;\u5c06 MCP \u670d\u52a1\u5668\u7684\u5de5\u5177\u540c\u6b65\u5230\u6ce8\u518c\u8868<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">start_sync<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> interval <span class=\"token operator\">&#061;<\/span> <span class=\"token namespace\">tokio<span class=\"token punctuation\">::<\/span>time<span class=\"token punctuation\">::<\/span><\/span><span class=\"token function\">interval<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>sync_interval<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">loop<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            interval<span class=\"token punctuation\">.<\/span><span class=\"token function\">tick<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token keyword\">match<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>mcp_client<span class=\"token punctuation\">.<\/span><span class=\"token function\">list_tools<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>mcp_tools<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">for<\/span> mcp_tool <span class=\"token keyword\">in<\/span> mcp_tools <span class=\"token punctuation\">{<\/span><br \/>\n                        <span class=\"token keyword\">let<\/span> descriptor <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">convert_to_descriptor<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>mcp_tool<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>                        <span class=\"token comment\">\/\/ \u6ce8\u518c\u6216\u66f4\u65b0\u5de5\u5177<\/span><br \/>\n                        <span class=\"token keyword\">match<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>registry<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>descriptor<span class=\"token punctuation\">.<\/span>tool_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                            <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>existing<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">if<\/span> existing<span class=\"token punctuation\">.<\/span>version <span class=\"token operator\">&#061;&#061;<\/span> descriptor<span class=\"token punctuation\">.<\/span>version <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                                <span class=\"token comment\">\/\/ \u7248\u672c\u76f8\u540c&#xff0c;\u8df3\u8fc7<\/span><br \/>\n                            <span class=\"token punctuation\">}<\/span><br \/>\n                            _ <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                                <span class=\"token comment\">\/\/ \u6ce8\u518c\u65b0\u7248\u672c<\/span><br \/>\n                                <span class=\"token keyword\">let<\/span> executor <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">McpToolExecutor<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                    <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>mcp_client<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                                    mcp_tool<span class=\"token punctuation\">.<\/span>name<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                                <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                                <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>registry<span class=\"token punctuation\">.<\/span><span class=\"token function\">register<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                    descriptor<span class=\"token punctuation\">,<\/span><br \/>\n                                    <span class=\"token class-name\">Arc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span>executor<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                                <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                            <span class=\"token punctuation\">}<\/span><br \/>\n                        <span class=\"token punctuation\">}<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><\/p>\n<p>                    <span class=\"token namespace\">tracing<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">info!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        server_id <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">%<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>server_id<span class=\"token punctuation\">,<\/span><br \/>\n                        tool_count <span class=\"token operator\">&#061;<\/span> mcp_tools<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        <span class=\"token string\">&#034;MCP tools synced&#034;<\/span><br \/>\n                    <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token class-name\">Err<\/span><span class=\"token punctuation\">(<\/span>e<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token namespace\">tracing<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">error!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        server_id <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">%<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>server_id<span class=\"token punctuation\">,<\/span><br \/>\n                        error <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">%<\/span>e<span class=\"token punctuation\">,<\/span><br \/>\n                        <span class=\"token string\">&#034;Failed to sync MCP tools&#034;<\/span><br \/>\n                    <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u5c06 MCP \u5de5\u5177\u63cf\u8ff0\u8f6c\u6362\u4e3a Gateway \u5de5\u5177\u63cf\u8ff0\u7b26<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">convert_to_descriptor<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> mcp_tool<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">McpTool<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">ToolDescriptor<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> tool_id <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">ToolId<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token string\">&#034;mcp:{}:{}&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>server_id<span class=\"token punctuation\">,<\/span> mcp_tool<span class=\"token punctuation\">.<\/span>name<br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">ToolDescriptor<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            tool_id<span class=\"token punctuation\">,<\/span><br \/>\n            name<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;mcp_{}_{}&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>server_id<span class=\"token punctuation\">,<\/span> mcp_tool<span class=\"token punctuation\">.<\/span>name<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            description<span class=\"token punctuation\">:<\/span> mcp_tool<span class=\"token punctuation\">.<\/span>description<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            version<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">SemVer<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            category<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ToolCategory<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">McpTool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            provider<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ToolProvider<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Mcp<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                server_id<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>server_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                tool_name<span class=\"token punctuation\">:<\/span> mcp_tool<span class=\"token punctuation\">.<\/span>name<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            input_schema<span class=\"token punctuation\">:<\/span> mcp_tool<span class=\"token punctuation\">.<\/span>input_schema<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            output_schema<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;type&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;object&#034;<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            timeout<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">from_secs<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">60<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            requires_sandbox<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            required_permissions<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token class-name\">Permission<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">UseMcpTools<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            rate_limit<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RateLimit<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                max_calls_per_minute<span class=\"token punctuation\">:<\/span> <span class=\"token number\">30<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                max_concurrent<span class=\"token punctuation\">:<\/span> <span class=\"token number\">3<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            status<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ToolStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Active<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            tags<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;mcp&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>server_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            stats<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ToolStats<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ MCP \u5de5\u5177\u6267\u884c\u5668&#xff08;\u5b9e\u73b0 ToolExecutor \u63a5\u53e3&#xff09;<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">McpToolExecutor<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    mcp_client<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">McpClient<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    tool_name<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[async_trait]<\/span><br \/>\n<span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">ToolExecutor<\/span> <span class=\"token keyword\">for<\/span> <span class=\"token class-name\">McpToolExecutor<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">execute<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        input<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        context<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">ExecutionContext<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolOutput<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">ToolError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> result <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>mcp_client<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">call_tool<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>tool_name<span class=\"token punctuation\">,<\/span> input<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">map_err<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>e<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token class-name\">ToolError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">ExecutionFailed<\/span><span class=\"token punctuation\">(<\/span>e<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ToolOutput<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            success<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">!<\/span>result<span class=\"token punctuation\">.<\/span>is_error<span class=\"token punctuation\">,<\/span><br \/>\n            result<span class=\"token punctuation\">:<\/span> result<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">.<\/span><span class=\"token function\">into<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            error<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">if<\/span> result<span class=\"token punctuation\">.<\/span>is_error <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ToolErrorInfo<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    code<span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;MCP_TOOL_ERROR&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    message<span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;MCP tool returned error&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token class-name\">None<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            metadata<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">OutputMetadata<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                execution_time_ms<span class=\"token punctuation\">:<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                tokens_used<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">health_check<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">ToolError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u68c0\u67e5 MCP \u5ba2\u6237\u7aef\u8fde\u63a5\u662f\u5426\u6d3b\u8dc3<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>mcp_client<span class=\"token punctuation\">.<\/span><span class=\"token function\">ping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>_<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>4.2.4 MCP \u670d\u52a1\u5668\u914d\u7f6e<\/h4>\n<p><span class=\"token comment\"># MCP \u670d\u52a1\u5668\u914d\u7f6e\u793a\u4f8b<\/span><br \/>\n<span class=\"token key atrule\">mcp_servers<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token comment\"># \u672c\u5730\u6587\u4ef6\u7cfb\u7edf MCP \u670d\u52a1\u5668<\/span><br \/>\n  <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">id<\/span><span class=\"token punctuation\">:<\/span> filesystem<br \/>\n    <span class=\"token key atrule\">transport<\/span><span class=\"token punctuation\">:<\/span> stdio<br \/>\n    <span class=\"token key atrule\">command<\/span><span class=\"token punctuation\">:<\/span> npx<br \/>\n    <span class=\"token key atrule\">args<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token string\">&#034;&#064;modelcontextprotocol\/server-filesystem&#034;<\/span><br \/>\n      <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token string\">&#034;\/data\/workspace&#034;<\/span><br \/>\n    <span class=\"token key atrule\">env<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">NODE_ENV<\/span><span class=\"token punctuation\">:<\/span> production<br \/>\n    <span class=\"token key atrule\">auto_sync<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><br \/>\n    <span class=\"token key atrule\">sync_interval<\/span><span class=\"token punctuation\">:<\/span> 60s<\/p>\n<p>  <span class=\"token comment\"># GitHub MCP \u670d\u52a1\u5668<\/span><br \/>\n  <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">id<\/span><span class=\"token punctuation\">:<\/span> github<br \/>\n    <span class=\"token key atrule\">transport<\/span><span class=\"token punctuation\">:<\/span> stdio<br \/>\n    <span class=\"token key atrule\">command<\/span><span class=\"token punctuation\">:<\/span> npx<br \/>\n    <span class=\"token key atrule\">args<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token string\">&#034;&#064;modelcontextprotocol\/server-github&#034;<\/span><br \/>\n    <span class=\"token key atrule\">env<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">GITHUB_TOKEN<\/span><span class=\"token punctuation\">:<\/span> $<span class=\"token punctuation\">{<\/span>GITHUB_TOKEN<span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token key atrule\">auto_sync<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><\/p>\n<p>  <span class=\"token comment\"># \u8fdc\u7a0b MCP \u670d\u52a1\u5668&#xff08;SSE \u4f20\u8f93&#xff09;<\/span><br \/>\n  <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">id<\/span><span class=\"token punctuation\">:<\/span> knowledge_base<br \/>\n    <span class=\"token key atrule\">transport<\/span><span class=\"token punctuation\">:<\/span> sse<br \/>\n    <span class=\"token key atrule\">url<\/span><span class=\"token punctuation\">:<\/span> https<span class=\"token punctuation\">:<\/span>\/\/mcp.internal\/knowledge<span class=\"token punctuation\">&#8211;<\/span>base\/sse<br \/>\n    <span class=\"token key atrule\">headers<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">Authorization<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;Bearer ${MCP_KB_TOKEN}&#034;<\/span><br \/>\n    <span class=\"token key atrule\">auto_sync<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><br \/>\n    <span class=\"token key atrule\">sync_interval<\/span><span class=\"token punctuation\">:<\/span> 30s<\/p>\n<p>  <span class=\"token comment\"># \u81ea\u5b9a\u4e49 MCP \u670d\u52a1\u5668&#xff08;gRPC \u4f20\u8f93&#xff09;<\/span><br \/>\n  <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">id<\/span><span class=\"token punctuation\">:<\/span> data_pipeline<br \/>\n    <span class=\"token key atrule\">transport<\/span><span class=\"token punctuation\">:<\/span> grpc<br \/>\n    <span class=\"token key atrule\">endpoint<\/span><span class=\"token punctuation\">:<\/span> data<span class=\"token punctuation\">&#8211;<\/span>pipeline.internal<span class=\"token punctuation\">:<\/span><span class=\"token number\">50051<\/span><br \/>\n    <span class=\"token key atrule\">tls<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">enabled<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><br \/>\n      <span class=\"token key atrule\">cert_file<\/span><span class=\"token punctuation\">:<\/span> \/etc\/hermes\/certs\/client.crt<br \/>\n      <span class=\"token key atrule\">key_file<\/span><span class=\"token punctuation\">:<\/span> \/etc\/hermes\/certs\/client.key<br \/>\n      <span class=\"token key atrule\">ca_file<\/span><span class=\"token punctuation\">:<\/span> \/etc\/hermes\/certs\/ca.crt<br \/>\n    <span class=\"token key atrule\">auto_sync<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><\/p>\n<h3>4.3 \u5185\u7f6e\u5de5\u5177\u4e0e\u81ea\u5b9a\u4e49\u5de5\u5177\u7edf\u4e00\u7ba1\u7406<\/h3>\n<h4>4.3.1 \u5de5\u5177\u5206\u7c7b\u4f53\u7cfb<\/h4>\n<p>Hermes Agent \u7684\u5de5\u5177\u4f53\u7cfb\u5206\u4e3a\u4e09\u4e2a\u5c42\u7ea7&#xff0c;\u901a\u8fc7\u7edf\u4e00\u7684\u6ce8\u518c\u8868\u63a5\u53e3\u5b9e\u73b0\u65e0\u7f1d\u7ba1\u7406&#xff1a;<\/p>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502                    \u5de5\u5177\u5206\u7c7b\u4f53\u7cfb                                        \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u2502<br \/>\n\u2502  \u2502              \u5185\u7f6e\u5de5\u5177                \u2502   \u2502<br \/>\n\u2502  \u2502  \u00b7 \u4ee3\u7801\u6267\u884c\u5668        \u2502   \u2502<br \/>\n\u2502  \u2502  \u00b7 HTTP\u8bf7\u6c42 (           \u2502   \u2502<br \/>\n\u2502  \u2502  \u00b7 \u6587\u4ef6\u8bfb\u5199 (                 \u2502   \u2502<br \/>\n\u2502  \u2502  \u00b7 \u7f51\u7edc\u641c\u7d22 (             \u2502   \u2502<br \/>\n\u2502  \u2502  \u00b7 \u6570\u636e\u5206\u6790 (            \u2502   \u2502<br \/>\n\u2502  \u2502  \u00b7 \u56fe\u50cf\u751f\u6210 (          \u2502   \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518   \u2502<br \/>\n\u2502                              \u2502                                       \u2502<br \/>\n\u2502                              v                                       \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u2502<br \/>\n\u2502  \u2502              MCP \u5de5\u5177                 \u2502   \u2502<br \/>\n\u2502  \u2502  \u00b7 \u6587\u4ef6\u7cfb\u7edf MCP Server       \u2502   \u2502<br \/>\n\u2502  \u2502  \u00b7 GitHub MCP Server         \u2502   \u2502<br \/>\n\u2502  \u2502  \u00b7 \u77e5\u8bc6\u5e93 MCP Server         \u2502   \u2502<br \/>\n\u2502  \u2502  \u00b7 \u6570\u636e\u7ba1\u9053 MCP Server       \u2502   \u2502<br \/>\n\u2502  \u2502  \u00b7 \u81ea\u5b9a\u4e49 MCP Server         \u2502   \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518   \u2502<br \/>\n\u2502                              \u2502                                       \u2502<br \/>\n\u2502                              v                                       \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u2502<br \/>\n\u2502  \u2502              \u7528\u6237\u81ea\u5b9a\u4e49\u5de5\u5177       \u2502   \u2502<br \/>\n\u2502  \u2502  \u00b7 Python \u811a\u672c\u5de5\u5177           \u2502   \u2502<br \/>\n\u2502  \u2502  \u00b7 Shell \u547d\u4ee4\u5de5\u5177            \u2502   \u2502<br \/>\n\u2502  \u2502  \u00b7 API \u5c01\u88c5\u5de5\u5177              \u2502   \u2502<br \/>\n\u2502  \u2502  \u00b7 Workflow \u5de5\u5177             \u2502   \u2502<br \/>\n\u2502  \u2502  \u00b7 \u63d2\u4ef6\u5f0f\u5de5\u5177          \u2502   \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518   \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u7edf\u4e00\u63a5\u53e3: ToolExecutor trait                                        \u2502<br \/>\n\u2502  \u7edf\u4e00\u6ce8\u518c: ToolRegistry                                              \u2502<br \/>\n\u2502  \u7edf\u4e00\u53d1\u73b0: list_available_tools()                                    \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<h4>4.3.2 \u5185\u7f6e\u5de5\u5177\u5b9e\u73b0\u793a\u4f8b&#xff1a;\u4ee3\u7801\u6267\u884c\u5de5\u5177<\/h4>\n<p><span class=\"token comment\">\/\/\/ \u4ee3\u7801\u6267\u884c\u5de5\u5177<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">CodeExecutionTool<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    sandbox_manager<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SandboxManager<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    supported_languages<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[async_trait]<\/span><br \/>\n<span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">ToolExecutor<\/span> <span class=\"token keyword\">for<\/span> <span class=\"token class-name\">CodeExecutionTool<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">execute<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        input<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        context<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">ExecutionContext<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolOutput<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">ToolError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> language <span class=\"token operator\">&#061;<\/span> input<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;language&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">and_then<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>v<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> v<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_str<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">ok_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ToolError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">InvalidInput<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Missing language&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">into<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> code <span class=\"token operator\">&#061;<\/span> input<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;code&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">and_then<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>v<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> v<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_str<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">ok_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ToolError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">InvalidInput<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Missing code&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">into<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8bed\u8a00\u68c0\u67e5<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token operator\">!<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>supported_languages<span class=\"token punctuation\">.<\/span><span class=\"token function\">contains<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>language<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Err<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ToolError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">InvalidInput<\/span><span class=\"token punctuation\">(<\/span><span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                <span class=\"token string\">&#034;Unsupported language: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> language<br \/>\n            <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u5728\u6c99\u7bb1\u4e2d\u6267\u884c\u4ee3\u7801<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> sandbox <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>sandbox_manager<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">acquire_or_create<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>context<span class=\"token punctuation\">.<\/span>session_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> result <span class=\"token operator\">&#061;<\/span> sandbox<span class=\"token punctuation\">.<\/span><span class=\"token function\">execute_code<\/span><span class=\"token punctuation\">(<\/span>language<span class=\"token punctuation\">,<\/span> code<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u622a\u65ad\u8fc7\u957f\u7684\u8f93\u51fa<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> stdout <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">truncate_output<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>result<span class=\"token punctuation\">.<\/span>stdout<span class=\"token punctuation\">,<\/span> <span class=\"token number\">10000<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> stderr <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">truncate_output<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>result<span class=\"token punctuation\">.<\/span>stderr<span class=\"token punctuation\">,<\/span> <span class=\"token number\">5000<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ToolOutput<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            success<span class=\"token punctuation\">:<\/span> result<span class=\"token punctuation\">.<\/span>exit_code <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            result<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token string\">&#034;stdout&#034;<\/span><span class=\"token punctuation\">:<\/span> stdout<span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;stderr&#034;<\/span><span class=\"token punctuation\">:<\/span> stderr<span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;exit_code&#034;<\/span><span class=\"token punctuation\">:<\/span> result<span class=\"token punctuation\">.<\/span>exit_code<span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;execution_time_ms&#034;<\/span><span class=\"token punctuation\">:<\/span> result<span class=\"token punctuation\">.<\/span>execution_time_ms<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            error<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">if<\/span> result<span class=\"token punctuation\">.<\/span>exit_code <span class=\"token operator\">!&#061;<\/span> <span class=\"token number\">0<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ToolErrorInfo<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    code<span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;EXECUTION_FAILED&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    message<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        <span class=\"token string\">&#034;Process exited with code {}&#034;<\/span><span class=\"token punctuation\">,<\/span> result<span class=\"token punctuation\">.<\/span>exit_code<br \/>\n                    <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token class-name\">None<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            metadata<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">OutputMetadata<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                execution_time_ms<span class=\"token punctuation\">:<\/span> result<span class=\"token punctuation\">.<\/span>execution_time_ms<span class=\"token punctuation\">,<\/span><br \/>\n                tokens_used<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>result<span class=\"token punctuation\">.<\/span>tokens_used<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">health_check<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">ToolError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>sandbox_manager<span class=\"token punctuation\">.<\/span><span class=\"token function\">health_check<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">CodeExecutionTool<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">truncate_output<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> output<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span><span class=\"token punctuation\">,<\/span> max_len<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> output<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&lt;&#061;<\/span> max_len <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> output<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token string\">&#034;{}\\\\n&#8230;[output truncated, {} bytes total]&#8230;&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token operator\">&amp;<\/span>output<span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">..<\/span>max_len<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            output<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>4.3.3 \u81ea\u5b9a\u4e49\u5de5\u5177\u6ce8\u518c<\/h4>\n<p>\u7528\u6237\u53ef\u4ee5\u901a\u8fc7\u914d\u7f6e\u6587\u4ef6\u6216 API \u52a8\u6001\u6ce8\u518c\u81ea\u5b9a\u4e49\u5de5\u5177&#xff1a;<\/p>\n<p><span class=\"token comment\"># \u81ea\u5b9a\u4e49\u5de5\u5177\u914d\u7f6e<\/span><br \/>\n<span class=\"token key atrule\">custom_tools<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token comment\"># Python \u811a\u672c\u5de5\u5177<\/span><br \/>\n  <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> sentiment_analyzer<br \/>\n    <span class=\"token key atrule\">description<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;\u5206\u6790\u6587\u672c\u7684\u60c5\u611f\u503e\u5411&#xff0c;\u8fd4\u56de\u60c5\u611f\u5206\u6570\u548c\u5206\u7c7b&#034;<\/span><br \/>\n    <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> python_script<br \/>\n    <span class=\"token key atrule\">script<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">|<\/span><span class=\"token scalar string\"><br \/>\n      import json<br \/>\n      from textblob import TextBlob<\/span><\/p>\n<p>      <span class=\"token key atrule\">def execute(input_data)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n          text &#061; input_data.get(&#034;text&#034;<span class=\"token punctuation\">,<\/span> &#034;&#034;)<br \/>\n          blob &#061; TextBlob(text)<br \/>\n          sentiment &#061; blob.sentiment<br \/>\n          return <span class=\"token punctuation\">{<\/span><br \/>\n              <span class=\"token key atrule\">&#034;polarity&#034;<\/span><span class=\"token punctuation\">:<\/span> sentiment.polarity<span class=\"token punctuation\">,<\/span><br \/>\n              <span class=\"token key atrule\">&#034;subjectivity&#034;<\/span><span class=\"token punctuation\">:<\/span> sentiment.subjectivity<span class=\"token punctuation\">,<\/span><br \/>\n              <span class=\"token key atrule\">&#034;classification&#034;<\/span><span class=\"token punctuation\">:<\/span> &#034;positive&#034; if sentiment.polarity <span class=\"token punctuation\">&gt;<\/span> 0<br \/>\n                  else &#034;negative&#034; if sentiment.polarity &lt; 0<br \/>\n                  else &#034;neutral&#034;<br \/>\n          <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token key atrule\">input_schema<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> object<br \/>\n      <span class=\"token key atrule\">properties<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token key atrule\">text<\/span><span class=\"token punctuation\">:<\/span><br \/>\n          <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> string<br \/>\n          <span class=\"token key atrule\">description<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;\u5f85\u5206\u6790\u7684\u6587\u672c&#034;<\/span><br \/>\n      <span class=\"token key atrule\">required<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;text&#034;<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token key atrule\">timeout<\/span><span class=\"token punctuation\">:<\/span> 10s<br \/>\n    <span class=\"token key atrule\">requires_sandbox<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><br \/>\n    <span class=\"token key atrule\">permissions<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">[<\/span>UseCodeExecution<span class=\"token punctuation\">]<\/span><\/p>\n<p>  <span class=\"token comment\"># API \u5c01\u88c5\u5de5\u5177<\/span><br \/>\n  <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> weather_lookup<br \/>\n    <span class=\"token key atrule\">description<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;\u67e5\u8be2\u6307\u5b9a\u57ce\u5e02\u7684\u5929\u6c14\u4fe1\u606f&#034;<\/span><br \/>\n    <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> http_api<br \/>\n    <span class=\"token key atrule\">config<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">method<\/span><span class=\"token punctuation\">:<\/span> GET<br \/>\n      <span class=\"token key atrule\">url<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;https:\/\/api.weatherapi.com\/v1\/current.json&#034;<\/span><br \/>\n      <span class=\"token key atrule\">headers<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token key atrule\">&#034;X-API-Key&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;${WEATHER_API_KEY}&#034;<\/span><br \/>\n      <span class=\"token key atrule\">params<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token key atrule\">q<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;{{city}}&#034;<\/span><br \/>\n        <span class=\"token key atrule\">lang<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;zh&#034;<\/span><br \/>\n      <span class=\"token key atrule\">response_mapping<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token key atrule\">temperature<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;$.current.temp_c&#034;<\/span><br \/>\n        <span class=\"token key atrule\">condition<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;$.current.condition.text&#034;<\/span><br \/>\n        <span class=\"token key atrule\">humidity<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;$.current.humidity&#034;<\/span><br \/>\n        <span class=\"token key atrule\">wind_speed<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;$.current.wind_kph&#034;<\/span><br \/>\n    <span class=\"token key atrule\">input_schema<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> object<br \/>\n      <span class=\"token key atrule\">properties<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token key atrule\">city<\/span><span class=\"token punctuation\">:<\/span><br \/>\n          <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> string<br \/>\n          <span class=\"token key atrule\">description<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;\u57ce\u5e02\u540d\u79f0&#034;<\/span><br \/>\n      <span class=\"token key atrule\">required<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;city&#034;<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token key atrule\">timeout<\/span><span class=\"token punctuation\">:<\/span> 15s<br \/>\n    <span class=\"token key atrule\">permissions<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">[<\/span>UseExternalApi<span class=\"token punctuation\">]<\/span><\/p>\n<p>  <span class=\"token comment\"># Workflow \u5de5\u5177&#xff08;\u7ec4\u5408\u591a\u4e2a\u5de5\u5177&#xff09;<\/span><br \/>\n  <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> research_pipeline<br \/>\n    <span class=\"token key atrule\">description<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;\u7814\u7a76\u7ba1\u7ebf&#xff1a;\u641c\u7d22\u2192\u5206\u6790\u2192\u603b\u7ed3&#034;<\/span><br \/>\n    <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> workflow<br \/>\n    <span class=\"token key atrule\">steps<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> search<br \/>\n        <span class=\"token key atrule\">tool<\/span><span class=\"token punctuation\">:<\/span> web_search<br \/>\n        <span class=\"token key atrule\">input<\/span><span class=\"token punctuation\">:<\/span><br \/>\n          <span class=\"token key atrule\">query<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;{{topic}}&#034;<\/span><br \/>\n      <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> analyze<br \/>\n        <span class=\"token key atrule\">tool<\/span><span class=\"token punctuation\">:<\/span> sentiment_analyzer<br \/>\n        <span class=\"token key atrule\">input<\/span><span class=\"token punctuation\">:<\/span><br \/>\n          <span class=\"token key atrule\">text<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;{{search.result.summary}}&#034;<\/span><br \/>\n        <span class=\"token key atrule\">depends_on<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">[<\/span>search<span class=\"token punctuation\">]<\/span><br \/>\n      <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> summarize<br \/>\n        <span class=\"token key atrule\">tool<\/span><span class=\"token punctuation\">:<\/span> text_summarizer<br \/>\n        <span class=\"token key atrule\">input<\/span><span class=\"token punctuation\">:<\/span><br \/>\n          <span class=\"token key atrule\">text<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;{{search.result.content}}&#034;<\/span><br \/>\n          <span class=\"token key atrule\">max_length<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">500<\/span><br \/>\n        <span class=\"token key atrule\">depends_on<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">[<\/span>search<span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token key atrule\">output<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">search_results<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;{{search.result}}&#034;<\/span><br \/>\n      <span class=\"token key atrule\">sentiment<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;{{analyze.result}}&#034;<\/span><br \/>\n      <span class=\"token key atrule\">summary<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;{{summarize.result}}&#034;<\/span><br \/>\n    <span class=\"token key atrule\">timeout<\/span><span class=\"token punctuation\">:<\/span> 60s<br \/>\n    <span class=\"token key atrule\">permissions<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">[<\/span>UseWebSearch<span class=\"token punctuation\">,<\/span> UseCodeExecution<span class=\"token punctuation\">]<\/span><\/p>\n<h3>4.4 \u6743\u9650\u6821\u9a8c\u4e0e\u8c03\u7528\u5ba1\u8ba1<\/h3>\n<h4>4.4.1 \u6743\u9650\u6a21\u578b<\/h4>\n<p>Gateway \u91c7\u7528\u57fa\u4e8e\u89d2\u8272\u7684\u8bbf\u95ee\u63a7\u5236&#xff08;RBAC&#xff09;\u6a21\u578b\u7ba1\u7406\u5de5\u5177\u8c03\u7528\u6743\u9650&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u6743\u9650\u5b9a\u4e49<\/span><br \/>\n<span class=\"token attribute attr-name\">#[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">Permission<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4ee3\u7801\u6267\u884c<\/span><br \/>\n    <span class=\"token class-name\">UseCodeExecution<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7f51\u7edc\u8bf7\u6c42<\/span><br \/>\n    <span class=\"token class-name\">UseHttpRequest<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6587\u4ef6\u64cd\u4f5c<\/span><br \/>\n    <span class=\"token class-name\">UseFileOperation<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6570\u636e\u5e93\u64cd\u4f5c<\/span><br \/>\n    <span class=\"token class-name\">UseDatabase<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7f51\u7edc\u641c\u7d22<\/span><br \/>\n    <span class=\"token class-name\">UseWebSearch<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u77e5\u8bc6\u5e93\u67e5\u8be2<\/span><br \/>\n    <span class=\"token class-name\">UseKnowledgeQuery<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u56fe\u50cf\u5904\u7406<\/span><br \/>\n    <span class=\"token class-name\">UseImageProcessing<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5916\u90e8API<\/span><br \/>\n    <span class=\"token class-name\">UseExternalApi<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ MCP\u5de5\u5177<\/span><br \/>\n    <span class=\"token class-name\">UseMcpTools<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7ba1\u7406\u5458\u6743\u9650<\/span><br \/>\n    <span class=\"token class-name\">Admin<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u89d2\u8272<\/span><br \/>\n<span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">Role<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> role_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> name<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> permissions<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">HashSet<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Permission<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> tool_overrides<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolId<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">ToolPermission<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">ToolPermission<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Allowed<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">Denied<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">AllowedWithConditions<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Conditions<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">Conditions<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> max_calls_per_session<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">u32<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> allowed_params<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">AllowedValue<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> time_window<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">TimeWindow<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u6743\u9650\u6821\u9a8c\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">PermissionChecker<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u89d2\u8272-\u6743\u9650\u6620\u5c04<\/span><br \/>\n    roles<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Role<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7528\u6237-\u89d2\u8272\u6620\u5c04<\/span><br \/>\n    user_roles<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">UserId<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">PermissionChecker<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6821\u9a8c\u7528\u6237\u662f\u5426\u6709\u6743\u8c03\u7528\u6307\u5b9a\u5de5\u5177<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">check<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        user_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">UserId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        tool<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">ToolDescriptor<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        input<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">PermissionCheckResult<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">PermissionError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ 1. \u83b7\u53d6\u7528\u6237\u89d2\u8272<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> user_role_ids <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>user_roles<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>user_id<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">cloned<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or_default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> user_role_ids<span class=\"token punctuation\">.<\/span><span class=\"token function\">is_empty<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PermissionCheckResult<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Denied<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                reason<span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;User has no roles assigned&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 2. \u805a\u5408\u7528\u6237\u6743\u9650<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> roles <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>roles<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> aggregated_perms<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">HashSet<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Permission<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">HashSet<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> tool_overrides<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolId<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">ToolPermission<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">HashMap<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">for<\/span> role_id <span class=\"token keyword\">in<\/span> <span class=\"token operator\">&amp;<\/span>user_role_ids <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>role<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> roles<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>role_id<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                aggregated_perms<span class=\"token punctuation\">.<\/span><span class=\"token function\">extend<\/span><span class=\"token punctuation\">(<\/span>role<span class=\"token punctuation\">.<\/span>permissions<span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">cloned<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                tool_overrides<span class=\"token punctuation\">.<\/span><span class=\"token function\">extend<\/span><span class=\"token punctuation\">(<\/span>role<span class=\"token punctuation\">.<\/span>tool_overrides<span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span><span class=\"token punctuation\">(<\/span>k<span class=\"token punctuation\">,<\/span> v<span class=\"token punctuation\">)<\/span><span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token punctuation\">(<\/span>k<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> v<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 3. \u68c0\u67e5\u5de5\u5177\u7279\u5b9a\u8986\u76d6<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>override_perm<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> tool_overrides<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>tool<span class=\"token punctuation\">.<\/span>tool_id<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">match<\/span> override_perm <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token class-name\">ToolPermission<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Denied<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PermissionCheckResult<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Denied<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    reason<span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;Tool explicitly denied for user&#039;s role&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token class-name\">ToolPermission<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Allowed<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PermissionCheckResult<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Allowed<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token class-name\">ToolPermission<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">AllowedWithConditions<\/span><span class=\"token punctuation\">(<\/span>conditions<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">check_conditions<\/span><span class=\"token punctuation\">(<\/span>conditions<span class=\"token punctuation\">,<\/span> input<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 4. \u68c0\u67e5\u6240\u9700\u6743\u9650<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> required <span class=\"token keyword\">in<\/span> <span class=\"token operator\">&amp;<\/span>tool<span class=\"token punctuation\">.<\/span>required_permissions <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token operator\">!<\/span>aggregated_perms<span class=\"token punctuation\">.<\/span><span class=\"token function\">contains<\/span><span class=\"token punctuation\">(<\/span>required<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PermissionCheckResult<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Denied<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    reason<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        <span class=\"token string\">&#034;Missing required permission: {:?}&#034;<\/span><span class=\"token punctuation\">,<\/span> required<br \/>\n                    <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PermissionCheckResult<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Allowed<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">check_conditions<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        conditions<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">Conditions<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        input<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">PermissionCheckResult<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">PermissionError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u68c0\u67e5\u53c2\u6570\u767d\u540d\u5355<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>allowed_params<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>conditions<span class=\"token punctuation\">.<\/span>allowed_params <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span>param<span class=\"token punctuation\">,<\/span> allowed_value<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">in<\/span> allowed_params <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>value<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> input<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>param<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">if<\/span> <span class=\"token operator\">!<\/span>allowed_value<span class=\"token punctuation\">.<\/span><span class=\"token function\">matches<\/span><span class=\"token punctuation\">(<\/span>value<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PermissionCheckResult<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Denied<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                            reason<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                <span class=\"token string\">&#034;Parameter &#039;{}&#039; has disallowed value&#034;<\/span><span class=\"token punctuation\">,<\/span> param<br \/>\n                            <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u68c0\u67e5\u65f6\u95f4\u7a97\u53e3<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>time_window<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>conditions<span class=\"token punctuation\">.<\/span>time_window <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> now <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Utc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token operator\">!<\/span>time_window<span class=\"token punctuation\">.<\/span><span class=\"token function\">contains<\/span><span class=\"token punctuation\">(<\/span>now<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PermissionCheckResult<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Denied<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    reason<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        <span class=\"token string\">&#034;Current time outside allowed window: {:?}&#034;<\/span><span class=\"token punctuation\">,<\/span> time_window<br \/>\n                    <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PermissionCheckResult<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Allowed<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">PermissionCheckResult<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Allowed<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">Denied<\/span> <span class=\"token punctuation\">{<\/span> reason<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>4.4.2 \u8c03\u7528\u5ba1\u8ba1<\/h4>\n<p>\u6bcf\u6b21\u5de5\u5177\u8c03\u7528\u90fd\u88ab\u5b8c\u6574\u8bb0\u5f55&#xff0c;\u7528\u4e8e\u5ba1\u8ba1\u3001\u5408\u89c4\u548c\u6027\u80fd\u5206\u6790&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u5de5\u5177\u8c03\u7528\u5ba1\u8ba1\u65e5\u5fd7<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">AuditLogger<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u65e5\u5fd7\u5199\u5165\u5668&#xff08;\u6279\u91cf\u5199\u5165&#xff09;<\/span><br \/>\n    writer<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">BatchLogWriter<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u654f\u611f\u53c2\u6570\u8131\u654f\u5668<\/span><br \/>\n    masker<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SensitiveDataMasker<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">AuditEntry<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5ba1\u8ba1ID<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> audit_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u8c03\u7528\u65f6\u95f4<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> timestamp<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">DateTime<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4f1a\u8bddID<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> session_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7528\u6237ID<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> user_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">UserId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5de5\u5177ID<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> tool_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ToolId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5de5\u5177\u540d\u79f0<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> tool_name<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u8f93\u5165\u53c2\u6570&#xff08;\u8131\u654f\u540e&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> input<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u8f93\u51fa\u7ed3\u679c&#xff08;\u8131\u654f\u540e&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> output<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u662f\u5426\u6210\u529f<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> success<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u9519\u8bef\u4fe1\u606f<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> error<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6267\u884c\u8017\u65f6<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> duration_ms<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u8c03\u7528\u6765\u6e90&#xff08;LLM\u51b3\u7b56\/\u7528\u6237\u6307\u5b9a\/\u7cfb\u7edf\u81ea\u52a8&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> source<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">CallSource<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6c99\u7bb1ID<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> sandbox_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u8ffd\u8e2aID<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> trace_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">CallSource<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">LlmDecision<\/span> <span class=\"token punctuation\">{<\/span> model<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> reasoning<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">UserSpecified<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">SystemAutomatic<\/span> <span class=\"token punctuation\">{<\/span> trigger<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">Workflow<\/span> <span class=\"token punctuation\">{<\/span> workflow_name<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> step<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">AuditLogger<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u8bb0\u5f55\u5de5\u5177\u8c03\u7528<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">log<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> entry<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">AuditEntry<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">AuditError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u8131\u654f\u5904\u7406<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> masked_entry <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">AuditEntry<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            input<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>masker<span class=\"token punctuation\">.<\/span><span class=\"token function\">mask<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>entry<span class=\"token punctuation\">.<\/span>input<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            output<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">match<\/span> <span class=\"token operator\">&amp;<\/span>entry<span class=\"token punctuation\">.<\/span>output <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>o<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>masker<span class=\"token punctuation\">.<\/span><span class=\"token function\">mask<\/span><span class=\"token punctuation\">(<\/span>o<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token class-name\">None<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">..<\/span>entry<br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u6279\u91cf\u5199\u5165<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>writer<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span>masked_entry<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u67e5\u8be2\u5ba1\u8ba1\u65e5\u5fd7<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">query<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        filter<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">AuditFilter<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">AuditEntry<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">AuditError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>writer<span class=\"token punctuation\">.<\/span><span class=\"token function\">query<\/span><span class=\"token punctuation\">(<\/span>filter<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u5ba1\u8ba1\u67e5\u8be2\u8fc7\u6ee4\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">AuditFilter<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> session_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> user_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">UserId<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> tool_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolId<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> start_time<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">DateTime<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> end_time<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">DateTime<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> success_only<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">bool<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> limit<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u5ba1\u8ba1\u65e5\u5fd7\u7684\u5178\u578b\u67e5\u8be2\u573a\u666f&#xff1a;<\/p>\n<p><span class=\"token comment\">&#8212; \u67e5\u8be2\u67d0\u7528\u6237\u5728\u6307\u5b9a\u65f6\u95f4\u6bb5\u7684\u6240\u6709\u5de5\u5177\u8c03\u7528<\/span><br \/>\n<span class=\"token keyword\">SELECT<\/span> <span class=\"token operator\">*<\/span> <span class=\"token keyword\">FROM<\/span> audit_logs<br \/>\n<span class=\"token keyword\">WHERE<\/span> user_id <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#039;user_123&#039;<\/span><br \/>\n  <span class=\"token operator\">AND<\/span> <span class=\"token keyword\">timestamp<\/span> <span class=\"token operator\">BETWEEN<\/span> <span class=\"token string\">&#039;2026-07-01&#039;<\/span> <span class=\"token operator\">AND<\/span> <span class=\"token string\">&#039;2026-07-07&#039;<\/span><br \/>\n<span class=\"token keyword\">ORDER<\/span> <span class=\"token keyword\">BY<\/span> <span class=\"token keyword\">timestamp<\/span> <span class=\"token keyword\">DESC<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token comment\">&#8212; \u67e5\u8be2\u5931\u8d25\u7684\u5de5\u5177\u8c03\u7528<\/span><br \/>\n<span class=\"token keyword\">SELECT<\/span> <span class=\"token operator\">*<\/span> <span class=\"token keyword\">FROM<\/span> audit_logs<br \/>\n<span class=\"token keyword\">WHERE<\/span> success <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><br \/>\n  <span class=\"token operator\">AND<\/span> <span class=\"token keyword\">timestamp<\/span> <span class=\"token operator\">&gt;<\/span> <span class=\"token function\">NOW<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#8211;<\/span> <span class=\"token keyword\">INTERVAL<\/span> <span class=\"token string\">&#039;24 hours&#039;<\/span><br \/>\n<span class=\"token keyword\">ORDER<\/span> <span class=\"token keyword\">BY<\/span> <span class=\"token keyword\">timestamp<\/span> <span class=\"token keyword\">DESC<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token comment\">&#8212; \u6309\u5de5\u5177\u7edf\u8ba1\u8c03\u7528\u9891\u6b21\u548c\u6210\u529f\u7387<\/span><br \/>\n<span class=\"token keyword\">SELECT<\/span><br \/>\n    tool_name<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">COUNT<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">*<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> total_calls<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">SUM<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">CASE<\/span> <span class=\"token keyword\">WHEN<\/span> success <span class=\"token keyword\">THEN<\/span> <span class=\"token number\">1<\/span> <span class=\"token keyword\">ELSE<\/span> <span class=\"token number\">0<\/span> <span class=\"token keyword\">END<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> successful<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">AVG<\/span><span class=\"token punctuation\">(<\/span>duration_ms<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> avg_duration<br \/>\n<span class=\"token keyword\">FROM<\/span> audit_logs<br \/>\n<span class=\"token keyword\">WHERE<\/span> <span class=\"token keyword\">timestamp<\/span> <span class=\"token operator\">&gt;<\/span> <span class=\"token function\">NOW<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#8211;<\/span> <span class=\"token keyword\">INTERVAL<\/span> <span class=\"token string\">&#039;7 days&#039;<\/span><br \/>\n<span class=\"token keyword\">GROUP<\/span> <span class=\"token keyword\">BY<\/span> tool_name<span class=\"token punctuation\">;<\/span><\/p>\n<h3>4.5 \u5de5\u5177\u7248\u672c\u7ba1\u7406\u4e0e\u70ed\u66f4\u65b0<\/h3>\n<h4>4.5.1 \u7248\u672c\u7ba1\u7406\u7b56\u7565<\/h4>\n<p><span class=\"token comment\">\/\/\/ \u5de5\u5177\u7248\u672c\u7ba1\u7406\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ToolVersionManager<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7248\u672c\u5386\u53f2&#xff1a;ToolId -&gt; Vec&lt;VersionEntry&gt;<\/span><br \/>\n    version_history<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolId<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">VersionEntry<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6d3b\u8dc3\u7248\u672c&#xff1a;ToolId -&gt; Version<\/span><br \/>\n    active_versions<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolId<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">SemVer<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7070\u5ea6\u53d1\u5e03\u914d\u7f6e<\/span><br \/>\n    rollout_config<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolId<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">RolloutConfig<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">VersionEntry<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> version<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">SemVer<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> descriptor<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ToolDescriptor<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> registered_at<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">DateTime<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> status<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">VersionStatus<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug, PartialEq, Eq)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">VersionStatus<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Active<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">Inactive<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">Deprecated<\/span> <span class=\"token punctuation\">{<\/span> sunset_date<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">DateTime<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">Retired<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">RolloutConfig<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> strategy<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">RolloutStrategy<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> percentage<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u8<\/span><span class=\"token punctuation\">,<\/span>  <span class=\"token comment\">\/\/ 0-100<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> target_sessions<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> target_users<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">UserId<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">RolloutStrategy<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5168\u91cf\u53d1\u5e03<\/span><br \/>\n    <span class=\"token class-name\">Full<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u767e\u5206\u6bd4\u7070\u5ea6<\/span><br \/>\n    <span class=\"token class-name\">Percentage<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u767d\u540d\u5355\u7070\u5ea6<\/span><br \/>\n    <span class=\"token class-name\">Whitelist<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u91d1\u4e1d\u96c0\u53d1\u5e03<\/span><br \/>\n    <span class=\"token class-name\">Canary<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">ToolVersionManager<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6ce8\u518c\u65b0\u7248\u672c&#xff08;\u4e0d\u7acb\u5373\u6fc0\u6d3b&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">register_version<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        descriptor<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ToolDescriptor<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">VersionError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> tool_id <span class=\"token operator\">&#061;<\/span> descriptor<span class=\"token punctuation\">.<\/span>tool_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> version <span class=\"token operator\">&#061;<\/span> descriptor<span class=\"token punctuation\">.<\/span>version<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> history <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>version_history<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> entries <span class=\"token operator\">&#061;<\/span> history<span class=\"token punctuation\">.<\/span><span class=\"token function\">entry<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">or_default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u68c0\u67e5\u7248\u672c\u662f\u5426\u5df2\u5b58\u5728<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> entries<span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">any<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>e<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> e<span class=\"token punctuation\">.<\/span>version <span class=\"token operator\">&#061;&#061;<\/span> version<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Err<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">VersionError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">VersionAlreadyExists<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                tool_id<span class=\"token punctuation\">,<\/span> version<br \/>\n            <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        entries<span class=\"token punctuation\">.<\/span><span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">VersionEntry<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            version<span class=\"token punctuation\">:<\/span> version<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            descriptor<span class=\"token punctuation\">,<\/span><br \/>\n            registered_at<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Utc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            status<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">VersionStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Inactive<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u6fc0\u6d3b\u6307\u5b9a\u7248\u672c&#xff08;\u70ed\u66f4\u65b0&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">activate_version<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        tool_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">ToolId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        version<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SemVer<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">VersionError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> history <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>version_history<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> entries <span class=\"token operator\">&#061;<\/span> history<span class=\"token punctuation\">.<\/span><span class=\"token function\">get_mut<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">ok_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">VersionError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">ToolNotFound<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u627e\u5230\u76ee\u6807\u7248\u672c\u5e76\u6fc0\u6d3b<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> entry <span class=\"token keyword\">in<\/span> entries<span class=\"token punctuation\">.<\/span><span class=\"token function\">iter_mut<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> entry<span class=\"token punctuation\">.<\/span>version <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token operator\">*<\/span>version <span class=\"token punctuation\">{<\/span><br \/>\n                entry<span class=\"token punctuation\">.<\/span>status <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">VersionStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Active<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token keyword\">if<\/span> entry<span class=\"token punctuation\">.<\/span>status <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token class-name\">VersionStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Active<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                entry<span class=\"token punctuation\">.<\/span>status <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">VersionStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Inactive<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u66f4\u65b0\u6d3b\u8dc3\u7248\u672c<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>active_versions<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">insert<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> version<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token namespace\">tracing<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">info!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            tool_id <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">%<\/span>tool_id<span class=\"token punctuation\">,<\/span><br \/>\n            version <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">%<\/span>version<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;Tool version activated&#034;<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u7070\u5ea6\u53d1\u5e03&#xff1a;\u6839\u636e\u914d\u7f6e\u51b3\u5b9a\u4f7f\u7528\u54ea\u4e2a\u7248\u672c<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">resolve_version<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        tool_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">ToolId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        user_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">UserId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        session_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SemVer<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">VersionError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u68c0\u67e5\u662f\u5426\u6709\u7070\u5ea6\u914d\u7f6e<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> rollouts <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>rollout_config<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>config<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> rollouts<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">match<\/span> <span class=\"token operator\">&amp;<\/span>config<span class=\"token punctuation\">.<\/span>strategy <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token class-name\">RolloutStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Full<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get_latest_version<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token class-name\">RolloutStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Whitelist<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>target_users<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>config<span class=\"token punctuation\">.<\/span>target_users <span class=\"token punctuation\">{<\/span><br \/>\n                        <span class=\"token keyword\">if<\/span> target_users<span class=\"token punctuation\">.<\/span><span class=\"token function\">contains<\/span><span class=\"token punctuation\">(<\/span>user_id<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                            <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get_latest_version<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                        <span class=\"token punctuation\">}<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><br \/>\n                    <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>target_sessions<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>config<span class=\"token punctuation\">.<\/span>target_sessions <span class=\"token punctuation\">{<\/span><br \/>\n                        <span class=\"token keyword\">if<\/span> target_sessions<span class=\"token punctuation\">.<\/span><span class=\"token function\">contains<\/span><span class=\"token punctuation\">(<\/span>session_id<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                            <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get_latest_version<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                        <span class=\"token punctuation\">}<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token class-name\">RolloutStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Percentage<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token comment\">\/\/ \u57fa\u4e8e\u7528\u6237ID\u54c8\u5e0c\u51b3\u5b9a\u662f\u5426\u4f7f\u7528\u65b0\u7248\u672c<\/span><br \/>\n                    <span class=\"token keyword\">let<\/span> hash <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">hash_user<\/span><span class=\"token punctuation\">(<\/span>user_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    <span class=\"token keyword\">if<\/span> hash <span class=\"token operator\">%<\/span> <span class=\"token number\">100<\/span> <span class=\"token operator\">&lt;<\/span> config<span class=\"token punctuation\">.<\/span>percentage <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">u64<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                        <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get_latest_version<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token class-name\">RolloutStrategy<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Canary<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token comment\">\/\/ \u91d1\u4e1d\u96c0&#xff1a;\u5148\u5c0f\u8303\u56f4\u6d4b\u8bd5<\/span><br \/>\n                    <span class=\"token keyword\">if<\/span> config<span class=\"token punctuation\">.<\/span>percentage <span class=\"token operator\">&lt;<\/span> <span class=\"token number\">10<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                        <span class=\"token keyword\">let<\/span> hash <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">hash_user<\/span><span class=\"token punctuation\">(<\/span>user_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                        <span class=\"token keyword\">if<\/span> hash <span class=\"token operator\">%<\/span> <span class=\"token number\">100<\/span> <span class=\"token operator\">&lt;<\/span> config<span class=\"token punctuation\">.<\/span>percentage <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">u64<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                            <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get_latest_version<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                        <span class=\"token punctuation\">}<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                        <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get_latest_version<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u9ed8\u8ba4\u4f7f\u7528\u5f53\u524d\u6d3b\u8dc3\u7248\u672c<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>active_versions<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">cloned<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">ok_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">VersionError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">NoActiveVersion<\/span><span class=\"token punctuation\">(<\/span>tool_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>4.5.2 \u70ed\u66f4\u65b0\u6d41\u7a0b<\/h4>\n<p>\u5de5\u5177\u7684\u70ed\u66f4\u65b0\u4e0d\u9700\u8981\u91cd\u542f Gateway&#xff0c;\u6574\u4e2a\u6d41\u7a0b\u5982\u4e0b&#xff1a;<\/p>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502                    \u5de5\u5177\u70ed\u66f4\u65b0\u6d41\u7a0b                                       \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  1. \u6ce8\u518c\u65b0\u7248\u672c                                                        \u2502<br \/>\n\u2502     \u2514\u2500&gt; ToolRegistry.register(new_descriptor, new_executor)         \u2502<br \/>\n\u2502         \u65b0\u7248\u672c\u72b6\u6001: Inactive                                          \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  2. \u914d\u7f6e\u7070\u5ea6\u7b56\u7565                                                      \u2502<br \/>\n\u2502     \u2514\u2500&gt; RolloutConfig { strategy: Canary, percentage: 5 }           \u2502<br \/>\n\u2502         \u4ec55%\u7528\u6237\u4f7f\u7528\u65b0\u7248\u672c                                             \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  3. \u76d1\u63a7\u6307\u6807                                                          \u2502<br \/>\n\u2502     \u2514\u2500&gt; \u5bf9\u6bd4\u65b0\u65e7\u7248\u672c\u7684\u6210\u529f\u7387\u3001\u5ef6\u8fdf\u3001\u9519\u8bef\u7387                              \u2502<br \/>\n\u2502         \u5982\u679c\u65b0\u7248\u672c\u6307\u6807\u52a3\u5316 \u2192 \u81ea\u52a8\u56de\u6eda                                  \u2502<br \/>\n\u2502         \u5982\u679c\u65b0\u7248\u672c\u6307\u6807\u6b63\u5e38 \u2192 \u589e\u52a0\u7070\u5ea6\u6bd4\u4f8b                               \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  4. \u9010\u6b65\u6269\u5927\u8303\u56f4                                                      \u2502<br \/>\n\u2502     \u2514\u2500&gt; 5% \u2192 10% \u2192 25% \u2192 50% \u2192 100%                                \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  5. \u5168\u91cf\u6fc0\u6d3b                                                          \u2502<br \/>\n\u2502     \u2514\u2500&gt; VersionManager.activate_version(tool_id, new_version)       \u2502<br \/>\n\u2502         \u65e7\u7248\u672c\u72b6\u6001: Deprecated (\u4fdd\u755930\u5929\u540eRetired)                     \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  6. \u6e05\u7406\u65e7\u7248\u672c                                                        \u2502<br \/>\n\u2502     \u2514\u2500&gt; 30\u5929\u540e\u81ea\u52a8\u6267\u884c Retirement                                     \u2502<br \/>\n\u2502         \u65e7\u6267\u884c\u5668\u91ca\u653e\u8d44\u6e90                                               \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<p>\u70ed\u66f4\u65b0\u7684\u5173\u952e\u8bbe\u8ba1\u8003\u91cf&#xff1a;<\/p>\n<ul>\n<li>\u96f6\u505c\u673a&#xff1a;\u6574\u4e2a\u7248\u672c\u5207\u6362\u8fc7\u7a0b\u4e2d\u4e0d\u4e2d\u65ad\u4efb\u4f55\u6b63\u5728\u5904\u7406\u7684\u8bf7\u6c42<\/li>\n<li>\u6e10\u8fdb\u5f0f&#xff1a;\u4ece 5% \u5f00\u59cb\u9010\u6b65\u6269\u5927&#xff0c;\u6bcf\u6b65\u89c2\u5bdf\u81f3\u5c11 10 \u5206\u949f<\/li>\n<li>\u53ef\u56de\u6eda&#xff1a;\u4efb\u4f55\u9636\u6bb5\u53d1\u73b0\u95ee\u9898\u90fd\u80fd\u79d2\u7ea7\u56de\u6eda\u5230\u4e0a\u4e00\u7a33\u5b9a\u7248\u672c<\/li>\n<li>\u81ea\u52a8\u76d1\u63a7&#xff1a;\u7cfb\u7edf\u81ea\u52a8\u5bf9\u6bd4\u65b0\u65e7\u7248\u672c\u7684\u5173\u952e\u6307\u6807&#xff0c;\u5f02\u5e38\u65f6\u81ea\u52a8\u89e6\u53d1\u56de\u6eda<\/li>\n<li>\u517c\u5bb9\u6027\u4fdd\u8bc1&#xff1a;\u65b0\u7248\u672c\u5fc5\u987b\u5411\u540e\u517c\u5bb9\u65e7\u7248\u672c\u7684\u8f93\u5165\u8f93\u51fa\u683c\u5f0f<\/li>\n<\/ul>\n<hr \/>\n<h2>\u7b2c\u4e94\u7ae0 \u6838\u5fc3\u8def\u7531\u5f15\u64ce<\/h2>\n<p>\u6838\u5fc3\u8def\u7531\u5f15\u64ce\u662f Gateway \u7684\u300c\u5927\u8111\u300d&#xff0c;\u5b83\u63a5\u6536\u5f52\u4e00\u5316\u540e\u7684\u7528\u6237\u6d88\u606f&#xff0c;\u8bc6\u522b\u7528\u6237\u610f\u56fe&#xff0c;\u7f16\u6392\u4efb\u52a1\u6267\u884c\u8ba1\u5212&#xff0c;\u8c03\u5ea6\u8bb0\u5fc6\u4e0e\u5de5\u5177\u8d44\u6e90&#xff0c;\u6700\u7ec8\u4ea7\u51fa\u54cd\u5e94\u3002\u8def\u7531\u5f15\u64ce\u7684\u8bbe\u8ba1\u8d28\u91cf\u76f4\u63a5\u51b3\u5b9a\u4e86 Agent \u7684\u667a\u80fd\u6c34\u5e73\u548c\u54cd\u5e94\u6548\u7387\u3002<\/p>\n<h3>5.1 \u610f\u56fe\u8bc6\u522b\u7b97\u6cd5<\/h3>\n<h4>5.1.1 \u4e09\u7ea7\u610f\u56fe\u8bc6\u522b\u67b6\u6784<\/h4>\n<p>Hermes Agent \u91c7\u7528\u4e09\u7ea7\u7ea7\u8054\u7684\u610f\u56fe\u8bc6\u522b\u67b6\u6784&#xff0c;\u5728\u51c6\u786e\u7387\u548c\u5ef6\u8fdf\u4e4b\u95f4\u53d6\u5f97\u6700\u4f18\u5e73\u8861&#xff1a;<\/p>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502                  \u4e09\u7ea7\u610f\u56fe\u8bc6\u522b\u67b6\u6784                                       \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u7528\u6237\u8f93\u5165                                                             \u2502<br \/>\n\u2502      \u2502                                                               \u2502<br \/>\n\u2502      v                                                               \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                                                    \u2502<br \/>\n\u2502  \u2502 Level 1:     \u2502  \u5ef6\u8fdf: &lt;1ms                                        \u2502<br \/>\n\u2502  \u2502 \u89c4\u5219\u5339\u914d      \u2502  \u51c6\u786e\u7387: 60-70%                                    \u2502<br \/>\n\u2502  \u2502 (Rule-based) \u2502  \u8986\u76d6: \u9ad8\u9891\u660e\u786e\u610f\u56fe                                  \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                                                    \u2502<br \/>\n\u2502         \u2502 \u7f6e\u4fe1\u5ea6 &gt; 0.9?                                               \u2502<br \/>\n\u2502    \u250c\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2510                                                       \u2502<br \/>\n\u2502   Yes        No                                                      \u2502<br \/>\n\u2502    \u2502          \u2502                                                      \u2502<br \/>\n\u2502    v          v                                                      \u2502<br \/>\n\u2502  \u8fd4\u56de      \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                                           \u2502<br \/>\n\u2502  \u610f\u56fe      \u2502 Level 2:     \u2502  \u5ef6\u8fdf: 5-20ms                             \u2502<br \/>\n\u2502            \u2502 ML\u5206\u7c7b\u5668      \u2502  \u51c6\u786e\u7387: 85-90%                           \u2502<br \/>\n\u2502            \u2502 (ML Model)   \u2502  \u8986\u76d6: \u5e38\u89c1\u610f\u56fe                           \u2502<br \/>\n\u2502            \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                                          \u2502<br \/>\n\u2502                   \u2502 \u7f6e\u4fe1\u5ea6 &gt; 0.85?                                    \u2502<br \/>\n\u2502              \u250c\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2510                                             \u2502<br \/>\n\u2502             Yes        No                                            \u2502<br \/>\n\u2502              \u2502          \u2502                                            \u2502<br \/>\n\u2502              v          v                                            \u2502<br \/>\n\u2502            \u8fd4\u56de      \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                                 \u2502<br \/>\n\u2502            \u610f\u56fe      \u2502 Level 3:     \u2502  \u5ef6\u8fdf: 100-500ms               \u2502<br \/>\n\u2502                      \u2502 LLM\u63a8\u7406      \u2502  \u51c6\u786e\u7387: 95%&#043;                  \u2502<br \/>\n\u2502                      \u2502 (LLM-based)  \u2502  \u8986\u76d6: \u4efb\u610f\u610f\u56fe                 \u2502<br \/>\n\u2502                      \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                                \u2502<br \/>\n\u2502                             \u2502                                        \u2502<br \/>\n\u2502                             v                                        \u2502<br \/>\n\u2502                           \u8fd4\u56de\u610f\u56fe                                     \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<h4>5.1.2 Level 1&#xff1a;\u89c4\u5219\u5339\u914d\u5f15\u64ce<\/h4>\n<p><span class=\"token comment\">\/\/\/ \u89c4\u5219\u5339\u914d\u610f\u56fe\u8bc6\u522b\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">RuleBasedIntentDetector<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u610f\u56fe\u89c4\u5219\u96c6<\/span><br \/>\n    rules<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">IntentRule<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7f16\u8bd1\u540e\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u7f13\u5b58<\/span><br \/>\n    regex_cache<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Regex<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">IntentRule<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u610f\u56fe\u540d\u79f0<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> intent<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5339\u914d\u6a21\u5f0f<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> patterns<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">MatchPattern<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7f6e\u4fe1\u5ea6<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> confidence<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">f64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4f18\u5148\u7ea7&#xff08;\u6570\u5b57\u8d8a\u5927\u4f18\u5148\u7ea7\u8d8a\u9ad8&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> priority<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">i32<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">MatchPattern<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6b63\u5219\u5339\u914d<\/span><br \/>\n    <span class=\"token class-name\">Regex<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5173\u952e\u8bcd\u5305\u542b<\/span><br \/>\n    <span class=\"token class-name\">Keywords<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u524d\u7f00\u5339\u914d<\/span><br \/>\n    <span class=\"token class-name\">Prefix<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7cbe\u786e\u5339\u914d<\/span><br \/>\n    <span class=\"token class-name\">Exact<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">RuleBasedIntentDetector<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">detect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> input<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">IntentDetection<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u6309\u4f18\u5148\u7ea7\u6392\u5e8f\u7684\u89c4\u5219\u5339\u914d<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> matched_rules<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">IntentRule<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>rules<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">filter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>rule<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">matches<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">,<\/span> input<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        matched_rules<span class=\"token punctuation\">.<\/span><span class=\"token function\">sort_by<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>a<span class=\"token punctuation\">,<\/span> b<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> b<span class=\"token punctuation\">.<\/span>priority<span class=\"token punctuation\">.<\/span><span class=\"token function\">cmp<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>a<span class=\"token punctuation\">.<\/span>priority<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> matched_rules<span class=\"token punctuation\">.<\/span><span class=\"token function\">first<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">IntentDetection<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                intent<span class=\"token punctuation\">:<\/span> rule<span class=\"token punctuation\">.<\/span>intent<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                confidence<span class=\"token punctuation\">:<\/span> rule<span class=\"token punctuation\">.<\/span>confidence<span class=\"token punctuation\">,<\/span><br \/>\n                source<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">DetectionSource<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Rule<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                extracted_params<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">extract_params<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">,<\/span> input<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token class-name\">None<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">matches<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> rule<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">IntentRule<\/span><span class=\"token punctuation\">,<\/span> input<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token keyword\">bool<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> input_lower <span class=\"token operator\">&#061;<\/span> input<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_lowercase<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        rule<span class=\"token punctuation\">.<\/span>patterns<span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">any<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>pattern<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">match<\/span> pattern <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token class-name\">MatchPattern<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Regex<\/span><span class=\"token punctuation\">(<\/span>re_str<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>re<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>regex_cache<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>re_str<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                        re<span class=\"token punctuation\">.<\/span><span class=\"token function\">is_match<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>input_lower<span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                        <span class=\"token boolean\">false<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token class-name\">MatchPattern<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Keywords<\/span><span class=\"token punctuation\">(<\/span>keywords<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    keywords<span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">all<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>kw<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> input_lower<span class=\"token punctuation\">.<\/span><span class=\"token function\">contains<\/span><span class=\"token punctuation\">(<\/span>kw<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token class-name\">MatchPattern<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Prefix<\/span><span class=\"token punctuation\">(<\/span>prefix<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    input_lower<span class=\"token punctuation\">.<\/span><span class=\"token function\">starts_with<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>prefix<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_lowercase<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token class-name\">MatchPattern<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Exact<\/span><span class=\"token punctuation\">(<\/span>text<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    input_lower <span class=\"token operator\">&#061;&#061;<\/span> text<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_lowercase<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u9884\u5b9a\u4e49\u7684\u610f\u56fe\u89c4\u5219\u96c6<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">default_intent_rules<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">IntentRule<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><br \/>\n        <span class=\"token class-name\">IntentRule<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            intent<span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;code_execution&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">into<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            patterns<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><br \/>\n                <span class=\"token class-name\">MatchPattern<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Keywords<\/span><span class=\"token punctuation\">(<\/span><span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;\u8fd0\u884c&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;\u4ee3\u7801&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;\u6267\u884c&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token class-name\">MatchPattern<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Keywords<\/span><span class=\"token punctuation\">(<\/span><span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;run&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;code&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;execute&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token class-name\">MatchPattern<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Regex<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">r&#034;&#096;&#096;&#096;(python|javascript|rust|go)&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">into<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            confidence<span class=\"token punctuation\">:<\/span> <span class=\"token number\">0.95<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            priority<span class=\"token punctuation\">:<\/span> <span class=\"token number\">10<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">IntentRule<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            intent<span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;web_search&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">into<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            patterns<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><br \/>\n                <span class=\"token class-name\">MatchPattern<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Keywords<\/span><span class=\"token punctuation\">(<\/span><span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;\u641c\u7d22&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;\u67e5\u627e&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;\u67e5\u8be2&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token class-name\">MatchPattern<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Keywords<\/span><span class=\"token punctuation\">(<\/span><span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;search&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;find&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;lookup&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token class-name\">MatchPattern<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Prefix<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\u5e2e\u6211\u641c&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">into<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            confidence<span class=\"token punctuation\">:<\/span> <span class=\"token number\">0.90<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            priority<span class=\"token punctuation\">:<\/span> <span class=\"token number\">9<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">IntentRule<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            intent<span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;file_operation&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">into<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            patterns<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><br \/>\n                <span class=\"token class-name\">MatchPattern<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Keywords<\/span><span class=\"token punctuation\">(<\/span><span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;\u8bfb\u53d6&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;\u6587\u4ef6&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;\u4fdd\u5b58&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token class-name\">MatchPattern<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Keywords<\/span><span class=\"token punctuation\">(<\/span><span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;read&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;file&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;write&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;save&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            confidence<span class=\"token punctuation\">:<\/span> <span class=\"token number\">0.88<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            priority<span class=\"token punctuation\">:<\/span> <span class=\"token number\">8<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">IntentRule<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            intent<span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;knowledge_query&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">into<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            patterns<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><br \/>\n                <span class=\"token class-name\">MatchPattern<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Keywords<\/span><span class=\"token punctuation\">(<\/span><span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;\u77e5\u8bc6\u5e93&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;\u6587\u6863&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;\u624b\u518c&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token class-name\">MatchPattern<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Keywords<\/span><span class=\"token punctuation\">(<\/span><span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;knowledge&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;document&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;manual&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            confidence<span class=\"token punctuation\">:<\/span> <span class=\"token number\">0.85<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            priority<span class=\"token punctuation\">:<\/span> <span class=\"token number\">7<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">IntentRule<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            intent<span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;casual_chat&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">into<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            patterns<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><br \/>\n                <span class=\"token class-name\">MatchPattern<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Keywords<\/span><span class=\"token punctuation\">(<\/span><span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;\u4f60\u597d&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;\u55e8&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;hi&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;hello&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token class-name\">MatchPattern<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Keywords<\/span><span class=\"token punctuation\">(<\/span><span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;\u8c22\u8c22&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;thanks&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;thank you&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token class-name\">MatchPattern<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Keywords<\/span><span class=\"token punctuation\">(<\/span><span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;\u518d\u89c1&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;bye&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;goodbye&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            confidence<span class=\"token punctuation\">:<\/span> <span class=\"token number\">0.92<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            priority<span class=\"token punctuation\">:<\/span> <span class=\"token number\">5<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">]<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>5.1.3 Level 2&#xff1a;ML \u5206\u7c7b\u5668<\/h4>\n<p>\u5f53\u89c4\u5219\u5339\u914d\u7684\u7f6e\u4fe1\u5ea6\u4e0d\u8db3\u65f6&#xff0c;Gateway \u4f7f\u7528\u8f7b\u91cf\u7ea7 ML \u6a21\u578b\u8fdb\u884c\u610f\u56fe\u5206\u7c7b\u3002\u8be5\u6a21\u578b\u57fa\u4e8e BERT-tiny \u5fae\u8c03&#xff0c;\u5728 CPU \u4e0a\u63a8\u7406\u5ef6\u8fdf\u7ea6 5-20ms&#xff1a;<\/p>\n<p><span class=\"token comment\"># \u610f\u56fe\u5206\u7c7b\u6a21\u578b\u8bad\u7ec3\u811a\u672c (\u7b80\u5316\u7248)<\/span><br \/>\n<span class=\"token keyword\">import<\/span> torch<br \/>\n<span class=\"token keyword\">from<\/span> transformers <span class=\"token keyword\">import<\/span> BertTokenizerFast<span class=\"token punctuation\">,<\/span> BertForSequenceClassification<br \/>\n<span class=\"token keyword\">from<\/span> torch<span class=\"token punctuation\">.<\/span>utils<span class=\"token punctuation\">.<\/span>data <span class=\"token keyword\">import<\/span> Dataset<span class=\"token punctuation\">,<\/span> DataLoader<\/p>\n<p><span class=\"token keyword\">class<\/span> <span class=\"token class-name\">IntentDataset<\/span><span class=\"token punctuation\">(<\/span>Dataset<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">def<\/span> <span class=\"token function\">__init__<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> texts<span class=\"token punctuation\">,<\/span> labels<span class=\"token punctuation\">,<\/span> tokenizer<span class=\"token punctuation\">,<\/span> max_len<span class=\"token operator\">&#061;<\/span><span class=\"token number\">128<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>texts <span class=\"token operator\">&#061;<\/span> texts<br \/>\n        self<span class=\"token punctuation\">.<\/span>labels <span class=\"token operator\">&#061;<\/span> labels<br \/>\n        self<span class=\"token punctuation\">.<\/span>tokenizer <span class=\"token operator\">&#061;<\/span> tokenizer<br \/>\n        self<span class=\"token punctuation\">.<\/span>max_len <span class=\"token operator\">&#061;<\/span> max_len<\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">__len__<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token builtin\">len<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">.<\/span>texts<span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">__getitem__<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> idx<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        text <span class=\"token operator\">&#061;<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">.<\/span>texts<span class=\"token punctuation\">[<\/span>idx<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        encoding <span class=\"token operator\">&#061;<\/span> self<span class=\"token punctuation\">.<\/span>tokenizer<span class=\"token punctuation\">(<\/span><br \/>\n            text<span class=\"token punctuation\">,<\/span><br \/>\n            max_length<span class=\"token operator\">&#061;<\/span>self<span class=\"token punctuation\">.<\/span>max_len<span class=\"token punctuation\">,<\/span><br \/>\n            padding<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#039;max_length&#039;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            truncation<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">True<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            return_tensors<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#039;pt&#039;<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token string\">&#039;input_ids&#039;<\/span><span class=\"token punctuation\">:<\/span> encoding<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;input_ids&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>flatten<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#039;attention_mask&#039;<\/span><span class=\"token punctuation\">:<\/span> encoding<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;attention_mask&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>flatten<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#039;labels&#039;<\/span><span class=\"token punctuation\">:<\/span> torch<span class=\"token punctuation\">.<\/span>tensor<span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">.<\/span>labels<span class=\"token punctuation\">[<\/span>idx<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span> dtype<span class=\"token operator\">&#061;<\/span>torch<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">long<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\"># \u610f\u56fe\u6807\u7b7e<\/span><br \/>\nINTENT_LABELS <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><br \/>\n    <span class=\"token string\">&#034;code_execution&#034;<\/span><span class=\"token punctuation\">,<\/span>    <span class=\"token comment\"># \u4ee3\u7801\u6267\u884c<\/span><br \/>\n    <span class=\"token string\">&#034;web_search&#034;<\/span><span class=\"token punctuation\">,<\/span>        <span class=\"token comment\"># \u7f51\u7edc\u641c\u7d22<\/span><br \/>\n    <span class=\"token string\">&#034;file_operation&#034;<\/span><span class=\"token punctuation\">,<\/span>    <span class=\"token comment\"># \u6587\u4ef6\u64cd\u4f5c<\/span><br \/>\n    <span class=\"token string\">&#034;knowledge_query&#034;<\/span><span class=\"token punctuation\">,<\/span>   <span class=\"token comment\"># \u77e5\u8bc6\u5e93\u67e5\u8be2<\/span><br \/>\n    <span class=\"token string\">&#034;data_analysis&#034;<\/span><span class=\"token punctuation\">,<\/span>     <span class=\"token comment\"># \u6570\u636e\u5206\u6790<\/span><br \/>\n    <span class=\"token string\">&#034;image_generation&#034;<\/span><span class=\"token punctuation\">,<\/span>  <span class=\"token comment\"># \u56fe\u50cf\u751f\u6210<\/span><br \/>\n    <span class=\"token string\">&#034;translation&#034;<\/span><span class=\"token punctuation\">,<\/span>       <span class=\"token comment\"># \u7ffb\u8bd1<\/span><br \/>\n    <span class=\"token string\">&#034;summarization&#034;<\/span><span class=\"token punctuation\">,<\/span>     <span class=\"token comment\"># \u6458\u8981<\/span><br \/>\n    <span class=\"token string\">&#034;casual_chat&#034;<\/span><span class=\"token punctuation\">,<\/span>       <span class=\"token comment\"># \u65e5\u5e38\u95f2\u804a<\/span><br \/>\n    <span class=\"token string\">&#034;task_planning&#034;<\/span><span class=\"token punctuation\">,<\/span>     <span class=\"token comment\"># \u4efb\u52a1\u89c4\u5212<\/span><br \/>\n    <span class=\"token string\">&#034;tool_orchestration&#034;<\/span><span class=\"token punctuation\">,<\/span><span class=\"token comment\"># \u5de5\u5177\u7f16\u6392<\/span><br \/>\n    <span class=\"token string\">&#034;unknown&#034;<\/span><span class=\"token punctuation\">,<\/span>           <span class=\"token comment\"># \u672a\u77e5\u610f\u56fe<\/span><br \/>\n<span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">class<\/span> <span class=\"token class-name\">IntentClassifier<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">def<\/span> <span class=\"token function\">__init__<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> model_path<span class=\"token punctuation\">:<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>tokenizer <span class=\"token operator\">&#061;<\/span> BertTokenizerFast<span class=\"token punctuation\">.<\/span>from_pretrained<span class=\"token punctuation\">(<\/span>model_path<span class=\"token punctuation\">)<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>model <span class=\"token operator\">&#061;<\/span> BertForSequenceClassification<span class=\"token punctuation\">.<\/span>from_pretrained<span class=\"token punctuation\">(<\/span>model_path<span class=\"token punctuation\">)<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>model<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">eval<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>labels <span class=\"token operator\">&#061;<\/span> INTENT_LABELS<\/p>\n<p>    <span class=\"token decorator annotation punctuation\">&#064;torch<span class=\"token punctuation\">.<\/span>no_grad<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">def<\/span> <span class=\"token function\">predict<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> text<span class=\"token punctuation\">:<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token builtin\">dict<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        encoding <span class=\"token operator\">&#061;<\/span> self<span class=\"token punctuation\">.<\/span>tokenizer<span class=\"token punctuation\">(<\/span><br \/>\n            text<span class=\"token punctuation\">,<\/span><br \/>\n            max_length<span class=\"token operator\">&#061;<\/span><span class=\"token number\">128<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            padding<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#039;max_length&#039;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            truncation<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">True<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            return_tensors<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#039;pt&#039;<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><\/p>\n<p>        outputs <span class=\"token operator\">&#061;<\/span> self<span class=\"token punctuation\">.<\/span>model<span class=\"token punctuation\">(<\/span><br \/>\n            input_ids<span class=\"token operator\">&#061;<\/span>encoding<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;input_ids&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            attention_mask<span class=\"token operator\">&#061;<\/span>encoding<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;attention_mask&#039;<\/span><span class=\"token punctuation\">]<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><\/p>\n<p>        probs <span class=\"token operator\">&#061;<\/span> torch<span class=\"token punctuation\">.<\/span>softmax<span class=\"token punctuation\">(<\/span>outputs<span class=\"token punctuation\">.<\/span>logits<span class=\"token punctuation\">,<\/span> dim<span class=\"token operator\">&#061;<\/span><span class=\"token operator\">&#8211;<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        confidence<span class=\"token punctuation\">,<\/span> predicted <span class=\"token operator\">&#061;<\/span> torch<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">max<\/span><span class=\"token punctuation\">(<\/span>probs<span class=\"token punctuation\">,<\/span> dim<span class=\"token operator\">&#061;<\/span><span class=\"token operator\">&#8211;<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token string\">&#039;intent&#039;<\/span><span class=\"token punctuation\">:<\/span> self<span class=\"token punctuation\">.<\/span>labels<span class=\"token punctuation\">[<\/span>predicted<span class=\"token punctuation\">.<\/span>item<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#039;confidence&#039;<\/span><span class=\"token punctuation\">:<\/span> confidence<span class=\"token punctuation\">.<\/span>item<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#039;all_probs&#039;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                label<span class=\"token punctuation\">:<\/span> prob<span class=\"token punctuation\">.<\/span>item<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token keyword\">for<\/span> label<span class=\"token punctuation\">,<\/span> prob <span class=\"token keyword\">in<\/span> <span class=\"token builtin\">zip<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">.<\/span>labels<span class=\"token punctuation\">,<\/span> probs<span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\"># \u63a8\u7406\u670d\u52a1\u5c01\u88c5<\/span><br \/>\n<span class=\"token keyword\">class<\/span> <span class=\"token class-name\">IntentDetectionService<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">def<\/span> <span class=\"token function\">__init__<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> model_path<span class=\"token punctuation\">:<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>classifier <span class=\"token operator\">&#061;<\/span> IntentClassifier<span class=\"token punctuation\">(<\/span>model_path<span class=\"token punctuation\">)<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>confidence_threshold <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0.85<\/span><\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">detect<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> text<span class=\"token punctuation\">:<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">,<\/span> context<span class=\"token punctuation\">:<\/span> <span class=\"token builtin\">dict<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">None<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token builtin\">dict<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        result <span class=\"token operator\">&#061;<\/span> self<span class=\"token punctuation\">.<\/span>classifier<span class=\"token punctuation\">.<\/span>predict<span class=\"token punctuation\">(<\/span>text<span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token comment\"># \u7ed3\u5408\u4e0a\u4e0b\u6587\u8c03\u6574\u7f6e\u4fe1\u5ea6<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> context <span class=\"token keyword\">and<\/span> <span class=\"token string\">&#039;recent_intents&#039;<\/span> <span class=\"token keyword\">in<\/span> context<span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token comment\"># \u5982\u679c\u6700\u8fd1\u51e0\u8f6e\u610f\u56fe\u4e00\u81f4&#xff0c;\u63d0\u5347\u7f6e\u4fe1\u5ea6<\/span><br \/>\n            recent <span class=\"token operator\">&#061;<\/span> context<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;recent_intents&#039;<\/span><span class=\"token punctuation\">]<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> recent <span class=\"token keyword\">and<\/span> recent<span class=\"token punctuation\">[<\/span><span class=\"token operator\">&#8211;<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> result<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;intent&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">:<\/span><br \/>\n                result<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;confidence&#039;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token builtin\">min<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    result<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;confidence&#039;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token number\">0.05<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">1.0<\/span><br \/>\n                <span class=\"token punctuation\">)<\/span><\/p>\n<p>        result<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;source&#039;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#039;ml_model&#039;<\/span><br \/>\n        result<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;passed&#039;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> result<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;confidence&#039;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&gt;&#061;<\/span> self<span class=\"token punctuation\">.<\/span>confidence_threshold<br \/>\n        <span class=\"token keyword\">return<\/span> result<\/p>\n<h4>5.1.4 Level 3&#xff1a;LLM \u63a8\u7406<\/h4>\n<p>\u5f53 ML \u5206\u7c7b\u5668\u7684\u7f6e\u4fe1\u5ea6\u4ecd\u7136\u4e0d\u8db3\u65f6&#xff0c;Gateway \u4f7f\u7528 LLM \u8fdb\u884c\u6df1\u5ea6\u610f\u56fe\u63a8\u7406\u3002\u8fd9\u4e00\u5c42\u7ea7\u4f7f\u7528\u4e13\u95e8\u7684\u63d0\u793a\u8bcd\u6a21\u677f&#xff0c;\u5f15\u5bfc LLM \u8fdb\u884c\u7ed3\u6784\u5316\u7684\u610f\u56fe\u5206\u6790&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ LLM \u610f\u56fe\u8bc6\u522b\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">LlmIntentDetector<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    model_router<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ModelRouter<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    prompt_template<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">LlmIntentDetector<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">detect<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        input<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        session_context<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">IntentDetection<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">IntentError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u6784\u5efa\u4e0a\u4e0b\u6587\u6458\u8981<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> context_summary <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">build_context_summary<\/span><span class=\"token punctuation\">(<\/span>session_context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u83b7\u53d6\u53ef\u7528\u5de5\u5177\u5217\u8868<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> available_tools <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get_available_tools_summary<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> prompt <span class=\"token operator\">&#061;<\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token string\">r#&#034;\u4f60\u662f\u4e00\u4e2a\u610f\u56fe\u8bc6\u522b\u4e13\u5bb6\u3002\u8bf7\u5206\u6790\u7528\u6237\u7684\u8f93\u5165&#xff0c;\u8bc6\u522b\u5176\u610f\u56fe\u3002<\/p>\n<p>## \u53ef\u7528\u610f\u56fe\u7c7b\u578b<br \/>\n&#8211; code_execution: \u6267\u884c\u4ee3\u7801<br \/>\n&#8211; web_search: \u641c\u7d22\u7f51\u7edc\u4fe1\u606f<br \/>\n&#8211; file_operation: \u6587\u4ef6\u8bfb\u5199\u64cd\u4f5c<br \/>\n&#8211; knowledge_query: \u77e5\u8bc6\u5e93\u67e5\u8be2<br \/>\n&#8211; data_analysis: \u6570\u636e\u5206\u6790<br \/>\n&#8211; image_generation: \u751f\u6210\u56fe\u50cf<br \/>\n&#8211; translation: \u7ffb\u8bd1<br \/>\n&#8211; summarization: \u5185\u5bb9\u6458\u8981<br \/>\n&#8211; casual_chat: \u65e5\u5e38\u95f2\u804a<br \/>\n&#8211; task_planning: \u4efb\u52a1\u89c4\u5212\u548c\u5206\u89e3<br \/>\n&#8211; tool_orchestration: \u7f16\u6392\u591a\u4e2a\u5de5\u5177<br \/>\n&#8211; multi_step: \u591a\u6b65\u9aa4\u590d\u6742\u4efb\u52a1<\/p>\n<p>## \u5bf9\u8bdd\u4e0a\u4e0b\u6587<br \/>\n{}<\/p>\n<p>## \u53ef\u7528\u5de5\u5177<br \/>\n{}<\/p>\n<p>## \u7528\u6237\u8f93\u5165<br \/>\n{}<\/p>\n<p>## \u8bf7\u4ee5JSON\u683c\u5f0f\u8f93\u51fa\u610f\u56fe\u5206\u6790\u7ed3\u679c&#xff1a;<br \/>\n{{<br \/>\n  &#034;intent&#034;: &#034;\u610f\u56fe\u540d\u79f0&#034;,<br \/>\n  &#034;confidence&#034;: 0.0-1.0,<br \/>\n  &#034;reasoning&#034;: &#034;\u8bc6\u522b\u7406\u7531&#034;,<br \/>\n  &#034;required_tools&#034;: [&#034;\u9700\u8981\u7684\u5de5\u5177\u5217\u8868&#034;],<br \/>\n  &#034;estimated_steps&#034;: \u4f30\u8ba1\u6b65\u9aa4\u6570,<br \/>\n  &#034;params&#034;: {{<br \/>\n    &#034;\u63d0\u53d6\u7684\u5173\u952e\u53c2\u6570&#034;: &#034;\u503c&#034;<br \/>\n  }}<br \/>\n}}&#034;#<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            context_summary<span class=\"token punctuation\">,<\/span><br \/>\n            available_tools<span class=\"token punctuation\">,<\/span><br \/>\n            input<br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u4f7f\u7528\u5feb\u901f\u6a21\u578b\u8fdb\u884c\u610f\u56fe\u63a8\u7406<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> response <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>model_router<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">complete<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ModelRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                model<span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;gpt-4o-mini&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">into<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span>  <span class=\"token comment\">\/\/ \u4f7f\u7528\u5feb\u901f\u6a21\u578b<\/span><br \/>\n                messages<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token class-name\">Message<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">user<\/span><span class=\"token punctuation\">(<\/span>prompt<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                temperature<span class=\"token punctuation\">:<\/span> <span class=\"token number\">0.1<\/span><span class=\"token punctuation\">,<\/span>  <span class=\"token comment\">\/\/ \u4f4e\u6e29\u5ea6\u4fdd\u8bc1\u4e00\u81f4\u6027<\/span><br \/>\n                max_tokens<span class=\"token punctuation\">:<\/span> <span class=\"token number\">500<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u89e3\u6790LLM\u8f93\u51fa\u7684JSON<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> detection<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">IntentDetection<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">parse_llm_response<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>response<span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">IntentDetection<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            source<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">DetectionSource<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Llm<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">..<\/span>detection<br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>5.1.5 \u610f\u56fe\u8bc6\u522b\u6548\u679c\u5bf9\u6bd4<\/h4>\n<table>\n<tr>\u8bc6\u522b\u5c42\u7ea7\u5e73\u5747\u5ef6\u8fdf\u51c6\u786e\u7387\u8986\u76d6\u7387\u8d44\u6e90\u6d88\u8017\u9002\u7528\u573a\u666f<\/tr>\n<tbody>\n<tr>\n<td>Level 1 (\u89c4\u5219)<\/td>\n<td>&lt;1ms<\/td>\n<td>95% (\u5339\u914d\u65f6)<\/td>\n<td>30-40%<\/td>\n<td>\u6781\u4f4e<\/td>\n<td>\u9ad8\u9891\u660e\u786e\u610f\u56fe<\/td>\n<\/tr>\n<tr>\n<td>Level 2 (ML)<\/td>\n<td>5-20ms<\/td>\n<td>88%<\/td>\n<td>70-80%<\/td>\n<td>\u4f4e (CPU)<\/td>\n<td>\u5e38\u89c1\u610f\u56fe\u5206\u7c7b<\/td>\n<\/tr>\n<tr>\n<td>Level 3 (LLM)<\/td>\n<td>100-500ms<\/td>\n<td>96%<\/td>\n<td>100%<\/td>\n<td>\u4e2d (GPU\/CPU)<\/td>\n<td>\u590d\u6742\/\u6a21\u7cca\u610f\u56fe<\/td>\n<\/tr>\n<tr>\n<td>\u4e09\u7ea7\u7ea7\u8054<\/td>\n<td>3-15ms (\u5e73\u5747)<\/td>\n<td>93%<\/td>\n<td>100%<\/td>\n<td>\u4f4e<\/td>\n<td>\u7efc\u5408\u6700\u4f18<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u4e09\u7ea7\u7ea7\u8054\u7684\u5e73\u5747\u5ef6\u8fdf\u8fdc\u4f4e\u4e8e\u5355\u72ec\u4f7f\u7528 LLM&#xff0c;\u56e0\u4e3a\u5927\u90e8\u5206\u8bf7\u6c42\u5728 Level 1 \u6216 Level 2 \u5c31\u80fd\u89e3\u51b3&#xff0c;\u53ea\u6709\u7ea6 15-20% \u7684\u8bf7\u6c42\u9700\u8981\u8fdb\u5165 Level 3\u3002<\/p>\n<h3>5.2 \u4efb\u52a1\u7f16\u6392\u7b56\u7565<\/h3>\n<h4>5.2.1 \u7f16\u6392\u6a21\u578b<\/h4>\n<p>\u610f\u56fe\u8bc6\u522b\u5b8c\u6210\u540e&#xff0c;\u8def\u7531\u5f15\u64ce\u6839\u636e\u610f\u56fe\u7c7b\u578b\u7f16\u6392\u4efb\u52a1\u6267\u884c\u8ba1\u5212\u3002Hermes Agent \u652f\u6301\u56db\u79cd\u7f16\u6392\u6a21\u5f0f&#xff1a;<\/p>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502                    \u4efb\u52a1\u7f16\u6392\u6a21\u5f0f                                         \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u6a21\u5f0f1: \u4e32\u884c\u6267\u884c                                    \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2510                                    \u2502<br \/>\n\u2502  \u2502 T1  \u2502\u2500\u2500\u2500&gt;\u2502 T2  \u2502\u2500\u2500\u2500&gt;\u2502 T3  \u2502                                    \u2502<br \/>\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u2500\u2518                                     \u2502<br \/>\n\u2502  \u6bcf\u4e2a\u4efb\u52a1\u7684\u8f93\u51fa\u4f5c\u4e3a\u4e0b\u4e00\u4e2a\u4efb\u52a1\u7684\u8f93\u5165                                     \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u6a21\u5f0f2: \u5e76\u884c\u6267\u884c                                     \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2510                                                              \u2502<br \/>\n\u2502  \u2502 T1  \u2502\u2572                                                            \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2518 \u2572    \u250c\u2500\u2500\u2500\u2500\u2500\u2510                                               \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2510  \u2573\u2500\u2500&gt;\u2502 \u805a\u5408 \u2502                                              \u2502<br \/>\n\u2502  \u2502 T2  \u2502\u2571    \u2514\u2500\u2500\u2500\u2500\u2500\u2518                                               \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2518                                                            \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2510                                                            \u2502<br \/>\n\u2502  \u2502 T3  \u2502\u2571                                                           \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2518    \u6240\u6709\u4efb\u52a1\u5e76\u884c\u6267\u884c&#xff0c;\u7ed3\u679c\u805a\u5408\u540e\u8fd4\u56de                           \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u6a21\u5f0f3: \u6761\u4ef6\u5206\u652f                                   \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2510         \u250c\u2500\u2500\u2500\u2500\u2500\u2510                                           \u2502<br \/>\n\u2502  \u2502 T1  \u2502\u2500\u2500&gt; if\u2500\u2500&gt;\u2502 T2  \u2502                                           \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2518    \u2572    \u2514\u2500\u2500\u2500\u2500\u2500\u2518                                           \u2502<br \/>\n\u2502              \u2572                                                      \u2502<br \/>\n\u2502               else \u2500&gt;\u250c\u2500\u2500\u2500\u2500\u2500\u2510                                       \u2502<br \/>\n\u2502                      \u2502 T3  \u2502                                       \u2502<br \/>\n\u2502                      \u2514\u2500\u2500\u2500\u2500\u2500\u2518                                       \u2502<br \/>\n\u2502  \u6839\u636e\u6761\u4ef6\u9009\u62e9\u6267\u884c\u8def\u5f84                                                 \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u6a21\u5f0f4: \u5faa\u73af\u8fed\u4ee3                                    \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510               \u2502<br \/>\n\u2502  \u2502 T1  \u2502\u2500\u2500\u2500&gt;\u2502 \u5224\u65ad\u6761\u4ef6 \u2502\u2500\u2500\u2500&gt;\u2502 T2  \u2502\u2500\u2500\u2500&gt;\u2502 \u7ee7\u7eed\u8fed\u4ee3? \u2502               \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2518               \u2502<br \/>\n\u2502                 \u2551                          \u2502 Yes                   \u2502<br \/>\n\u2502                 \u2551 &lt;\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u255b                       \u2502<br \/>\n\u2502                 \u2551                          \u2502 No                    \u2502<br \/>\n\u2502                 v                          v                       \u2502<br \/>\n\u2502              \u5b8c\u6210                        \u5b8c\u6210                       \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<h4>5.2.2 \u4efb\u52a1\u7f16\u6392\u5668\u5b9e\u73b0<\/h4>\n<p><span class=\"token comment\">\/\/\/ \u4efb\u52a1\u7f16\u6392\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">TaskOrchestrator<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    tool_registry<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ToolRegistry<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    model_router<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ModelRouter<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    max_depth<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    parallel_limit<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    timeout_per_task<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u4efb\u52a1\u6267\u884c\u8ba1\u5212<\/span><br \/>\n<span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ExecutionPlan<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> plan_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">PlanId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> intent<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> steps<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ExecutionStep<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> estimated_duration<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> estimated_tokens<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ExecutionStep<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> step_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> step_type<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">StepType<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> tool_name<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> input_template<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> depends_on<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> condition<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Condition<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> timeout<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">StepType<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">ToolCall<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">LlmCall<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">MemoryRead<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">MemoryWrite<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">Aggregation<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">Conditional<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">Loop<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">TaskOrchestrator<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6839\u636e\u610f\u56fe\u521b\u5efa\u6267\u884c\u8ba1\u5212<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">create_plan<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        intent<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">IntentDetection<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        context<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ExecutionPlan<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">OrchestrationError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">match<\/span> intent<span class=\"token punctuation\">.<\/span>intent<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_str<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token string\">&#034;code_execution&#034;<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">plan_code_execution<\/span><span class=\"token punctuation\">(<\/span>intent<span class=\"token punctuation\">,<\/span> context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;web_search&#034;<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">plan_web_search<\/span><span class=\"token punctuation\">(<\/span>intent<span class=\"token punctuation\">,<\/span> context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;knowledge_query&#034;<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">plan_knowledge_query<\/span><span class=\"token punctuation\">(<\/span>intent<span class=\"token punctuation\">,<\/span> context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;data_analysis&#034;<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">plan_data_analysis<\/span><span class=\"token punctuation\">(<\/span>intent<span class=\"token punctuation\">,<\/span> context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;task_planning&#034;<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">plan_task_decomposition<\/span><span class=\"token punctuation\">(<\/span>intent<span class=\"token punctuation\">,<\/span> context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;tool_orchestration&#034;<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">plan_tool_orchestration<\/span><span class=\"token punctuation\">(<\/span>intent<span class=\"token punctuation\">,<\/span> context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;multi_step&#034;<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">plan_multi_step<\/span><span class=\"token punctuation\">(<\/span>intent<span class=\"token punctuation\">,<\/span> context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;casual_chat&#034;<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">plan_simple_chat<\/span><span class=\"token punctuation\">(<\/span>intent<span class=\"token punctuation\">,<\/span> context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            _ <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">plan_default<\/span><span class=\"token punctuation\">(<\/span>intent<span class=\"token punctuation\">,<\/span> context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u6267\u884c\u8ba1\u5212<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">execute_plan<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        plan<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">ExecutionPlan<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        context<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">mut<\/span> <span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ExecutionResult<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">OrchestrationError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> step_results<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">HashMap<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> completed_steps<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">HashSet<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">HashSet<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u62d3\u6251\u6392\u5e8f\u786e\u5b9a\u6267\u884c\u987a\u5e8f<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> execution_order <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">topological_sort<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>plan<span class=\"token punctuation\">.<\/span>steps<span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">for<\/span> step_id <span class=\"token keyword\">in<\/span> execution_order <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> step <span class=\"token operator\">&#061;<\/span> plan<span class=\"token punctuation\">.<\/span>steps<span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">find<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>s<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> s<span class=\"token punctuation\">.<\/span>step_id <span class=\"token operator\">&#061;&#061;<\/span> step_id<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u68c0\u67e5\u6761\u4ef6<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>condition<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>step<span class=\"token punctuation\">.<\/span>condition <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">if<\/span> <span class=\"token operator\">!<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">evaluate_condition<\/span><span class=\"token punctuation\">(<\/span>condition<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span>step_results<span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">continue<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u7b49\u5f85\u4f9d\u8d56\u5b8c\u6210<\/span><br \/>\n            <span class=\"token keyword\">for<\/span> dep <span class=\"token keyword\">in<\/span> <span class=\"token operator\">&amp;<\/span>step<span class=\"token punctuation\">.<\/span>depends_on <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">if<\/span> <span class=\"token operator\">!<\/span>completed_steps<span class=\"token punctuation\">.<\/span><span class=\"token function\">contains<\/span><span class=\"token punctuation\">(<\/span>dep<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Err<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">OrchestrationError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">DependencyNotMet<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        step_id<span class=\"token punctuation\">,<\/span> dep<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u6e32\u67d3\u8f93\u5165\u6a21\u677f&#xff08;\u66ff\u6362\u53d8\u91cf\u5f15\u7528&#xff09;<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> input <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">render_template<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                <span class=\"token operator\">&amp;<\/span>step<span class=\"token punctuation\">.<\/span>input_template<span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token operator\">&amp;<\/span>step_results<span class=\"token punctuation\">,<\/span><br \/>\n                context<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u6267\u884c\u6b65\u9aa4<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> result <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">execute_step<\/span><span class=\"token punctuation\">(<\/span>step<span class=\"token punctuation\">,<\/span> input<span class=\"token punctuation\">,<\/span> context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            step_results<span class=\"token punctuation\">.<\/span><span class=\"token function\">insert<\/span><span class=\"token punctuation\">(<\/span>step_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> result<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            completed_steps<span class=\"token punctuation\">.<\/span><span class=\"token function\">insert<\/span><span class=\"token punctuation\">(<\/span>step_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u805a\u5408\u6700\u7ec8\u7ed3\u679c<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> final_result <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">aggregate_results<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>step_results<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span>plan<span class=\"token punctuation\">.<\/span>steps<span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ExecutionResult<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            plan_id<span class=\"token punctuation\">:<\/span> plan<span class=\"token punctuation\">.<\/span>plan_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            outputs<span class=\"token punctuation\">:<\/span> final_result<span class=\"token punctuation\">,<\/span><br \/>\n            step_count<span class=\"token punctuation\">:<\/span> completed_steps<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            status<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ExecutionStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Completed<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u6267\u884c\u5355\u4e2a\u6b65\u9aa4<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">execute_step<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        step<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">ExecutionStep<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        input<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        context<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">mut<\/span> <span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">OrchestrationError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">match<\/span> step<span class=\"token punctuation\">.<\/span>step_type <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">StepType<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">ToolCall<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">let<\/span> tool_name <span class=\"token operator\">&#061;<\/span> step<span class=\"token punctuation\">.<\/span>tool_name<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token keyword\">let<\/span> tool <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>tool_registry<span class=\"token punctuation\">.<\/span><span class=\"token function\">find_by_name<\/span><span class=\"token punctuation\">(<\/span>tool_name<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token keyword\">let<\/span> executor <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>tool_registry<span class=\"token punctuation\">.<\/span><span class=\"token function\">get_executor<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>tool<span class=\"token punctuation\">.<\/span>tool_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>                <span class=\"token keyword\">let<\/span> exec_context <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">ExecutionContext<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    session_id<span class=\"token punctuation\">:<\/span> context<span class=\"token punctuation\">.<\/span>session_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    user_id<span class=\"token punctuation\">:<\/span> context<span class=\"token punctuation\">.<\/span>user_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    tool_call_id<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">uuid<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Uuid<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new_v4<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    sandbox_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    deadline<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Instant<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#043;<\/span> step<span class=\"token punctuation\">.<\/span>timeout<span class=\"token punctuation\">,<\/span><br \/>\n                    permissions<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span>  <span class=\"token comment\">\/\/ \u4ece\u7528\u6237\u89d2\u8272\u83b7\u53d6<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>                <span class=\"token keyword\">let<\/span> output <span class=\"token operator\">&#061;<\/span> executor<span class=\"token punctuation\">.<\/span><span class=\"token function\">execute<\/span><span class=\"token punctuation\">(<\/span>input<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span>exec_context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>output<span class=\"token punctuation\">.<\/span>result<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token class-name\">StepType<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">LlmCall<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">let<\/span> response <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>model_router<br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">complete<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ModelRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                        model<span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;default&#034;<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">into<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        messages<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token class-name\">Message<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">user<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                            input<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;prompt&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                <span class=\"token punctuation\">.<\/span><span class=\"token function\">and_then<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>v<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> v<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_str<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                <span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                <span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        temperature<span class=\"token punctuation\">:<\/span> <span class=\"token number\">0.7<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        max_tokens<span class=\"token punctuation\">:<\/span> <span class=\"token number\">2000<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>                <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token string\">&#034;response&#034;<\/span><span class=\"token punctuation\">:<\/span> response<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token string\">&#034;tokens_used&#034;<\/span><span class=\"token punctuation\">:<\/span> response<span class=\"token punctuation\">.<\/span>tokens_used<span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token class-name\">StepType<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">MemoryRead<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token comment\">\/\/ \u4ece\u8bb0\u5fc6\u7cfb\u7edf\u8bfb\u53d6<\/span><br \/>\n                <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token string\">&#034;memories&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token class-name\">StepType<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">MemoryWrite<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token comment\">\/\/ \u5199\u5165\u8bb0\u5fc6\u7cfb\u7edf<\/span><br \/>\n                <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;success&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token class-name\">StepType<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Aggregation<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token comment\">\/\/ \u805a\u5408\u6b65\u9aa4\u7684\u7ed3\u679c<\/span><br \/>\n                <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>input<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            _ <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;status&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;skipped&#034;<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u6a21\u677f\u6e32\u67d3&#xff1a;\u66ff\u6362 {{step_id.field}} \u683c\u5f0f\u7684\u53d8\u91cf\u5f15\u7528<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">render_template<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        template<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        results<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        context<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">OrchestrationError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">match<\/span> template <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">(<\/span>s<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">let<\/span> rendered <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">replace_variables<\/span><span class=\"token punctuation\">(<\/span>s<span class=\"token punctuation\">,<\/span> results<span class=\"token punctuation\">,<\/span> context<span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">(<\/span>rendered<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Object<\/span><span class=\"token punctuation\">(<\/span>map<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> rendered <span class=\"token operator\">&#061;<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Map<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span>k<span class=\"token punctuation\">,<\/span> v<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">in<\/span> map <span class=\"token punctuation\">{<\/span><br \/>\n                    rendered<span class=\"token punctuation\">.<\/span><span class=\"token function\">insert<\/span><span class=\"token punctuation\">(<\/span>k<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">render_template<\/span><span class=\"token punctuation\">(<\/span>v<span class=\"token punctuation\">,<\/span> results<span class=\"token punctuation\">,<\/span> context<span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Object<\/span><span class=\"token punctuation\">(<\/span>rendered<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Array<\/span><span class=\"token punctuation\">(<\/span>arr<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> rendered <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token keyword\">for<\/span> v <span class=\"token keyword\">in<\/span> arr <span class=\"token punctuation\">{<\/span><br \/>\n                    rendered<span class=\"token punctuation\">.<\/span><span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">render_template<\/span><span class=\"token punctuation\">(<\/span>v<span class=\"token punctuation\">,<\/span> results<span class=\"token punctuation\">,<\/span> context<span class=\"token punctuation\">)<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Array<\/span><span class=\"token punctuation\">(<\/span>rendered<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n            _ <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>template<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">replace_variables<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        text<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        results<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        _context<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">OrchestrationError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u66ff\u6362 {{step_id.field}} \u683c\u5f0f\u7684\u5f15\u7528<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> result <span class=\"token operator\">&#061;<\/span> text<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u7b80\u5316\u7684\u53d8\u91cf\u66ff\u6362\u903b\u8f91<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span>step_id<span class=\"token punctuation\">,<\/span> value<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">in<\/span> results <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> placeholder <span class=\"token operator\">&#061;<\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;{{{{{}.result}}}}&#034;<\/span><span class=\"token punctuation\">,<\/span> step_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>s<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> value<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_str<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                result <span class=\"token operator\">&#061;<\/span> result<span class=\"token punctuation\">.<\/span><span class=\"token function\">replace<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>placeholder<span class=\"token punctuation\">,<\/span> s<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                result <span class=\"token operator\">&#061;<\/span> result<span class=\"token punctuation\">.<\/span><span class=\"token function\">replace<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>placeholder<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span>value<span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>result<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>5.2.3 \u7f16\u6392\u7b56\u7565\u793a\u4f8b<\/h4>\n<p>\u4ee5\u4e0b\u662f\u4e00\u4e2a\u590d\u6742\u4efb\u52a1\u7684\u591a\u6b65\u9aa4\u7f16\u6392\u793a\u4f8b\u2014\u2014\u201c\u5206\u6790\u67d0\u516c\u53f8\u7684\u8d22\u52a1\u6570\u636e\u5e76\u751f\u6210\u62a5\u544a\u201d&#xff1a;<\/p>\n<p><span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token string-property property\">&#034;plan_id&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;plan_001&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;intent&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;data_analysis&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;steps&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span><br \/>\n    <span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token string-property property\">&#034;step_id&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;fetch_data&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;step_type&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;ToolCall&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;tool_name&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;http_request&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;input_template&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token string-property property\">&#034;method&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;GET&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token string-property property\">&#034;url&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;https:\/\/api.finance.internal\/companies\/{{company_id}}\/financials&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token string-property property\">&#034;headers&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token string-property property\">&#034;Authorization&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;Bearer {{api_token}}&#034;<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n      <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;depends_on&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;timeout&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;15s&#034;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token string-property property\">&#034;step_id&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;parse_data&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;step_type&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;ToolCall&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;tool_name&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;code_execution&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;input_template&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token string-property property\">&#034;language&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;python&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token string-property property\">&#034;code&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;import json\\\\ndata &#061; json.loads(&#039;&#039;&#039;{{fetch_data.result}}&#039;&#039;&#039;)\\\\n# \u63d0\u53d6\u5173\u952e\u8d22\u52a1\u6307\u6807\\\\nmetrics &#061; {\\\\n  &#039;revenue&#039;: data[&#039;revenue&#039;],\\\\n  &#039;profit_margin&#039;: data[&#039;net_income&#039;] \/ data[&#039;revenue&#039;],\\\\n  &#039;debt_ratio&#039;: data[&#039;total_debt&#039;] \/ data[&#039;total_assets&#039;]\\\\n}\\\\nprint(json.dumps(metrics))&#034;<\/span><br \/>\n      <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;depends_on&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;fetch_data&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;timeout&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;10s&#034;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token string-property property\">&#034;step_id&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;search_benchmarks&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;step_type&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;ToolCall&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;tool_name&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;web_search&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;input_template&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token string-property property\">&#034;query&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;{{company_name}} \u884c\u4e1a\u5e73\u5747\u8d22\u52a1\u6307\u6807 \u57fa\u51c6&#034;<\/span><br \/>\n      <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;depends_on&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;timeout&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;15s&#034;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token string-property property\">&#034;step_id&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;analyze&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;step_type&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;LlmCall&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;input_template&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token string-property property\">&#034;prompt&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;\u57fa\u4e8e\u4ee5\u4e0b\u8d22\u52a1\u6570\u636e\u548c\u884c\u4e1a\u57fa\u51c6&#xff0c;\u8fdb\u884c\u6df1\u5ea6\u5206\u6790&#xff1a;\\\\n\\\\n\u516c\u53f8\u6570\u636e&#xff1a;{{parse_data.result}}\\\\n\u884c\u4e1a\u57fa\u51c6&#xff1a;{{search_benchmarks.result}}\\\\n\\\\n\u8bf7\u5206\u6790&#xff1a;1.\u8d22\u52a1\u5065\u5eb7\u72b6\u51b5 2.\u4e0e\u884c\u4e1a\u5bf9\u6bd4 3.\u98ce\u9669\u70b9 4.\u5efa\u8bae&#034;<\/span><br \/>\n      <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;depends_on&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;parse_data&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;search_benchmarks&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;timeout&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;30s&#034;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token string-property property\">&#034;step_id&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;save_memory&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;step_type&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;MemoryWrite&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;input_template&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token string-property property\">&#034;content&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;\u7528\u6237\u8bf7\u6c42\u5206\u6790{{company_name}}\u7684\u8d22\u52a1\u6570\u636e\u3002\u5206\u6790\u7ed3\u679c&#xff1a;{{analyze.result}}&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token string-property property\">&#034;type&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;analysis_result&#034;<\/span><br \/>\n      <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;depends_on&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;analyze&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;timeout&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;5s&#034;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token string-property property\">&#034;step_id&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;generate_report&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;step_type&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;LlmCall&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;input_template&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token string-property property\">&#034;prompt&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;\u5c06\u4ee5\u4e0b\u5206\u6790\u7ed3\u679c\u6574\u7406\u4e3a\u683c\u5f0f\u5316\u7684\u62a5\u544a&#xff1a;\\\\n\\\\n{{analyze.result}}\\\\n\\\\n\u8bf7\u4f7f\u7528Markdown\u683c\u5f0f&#xff0c;\u5305\u542b\u6807\u9898\u3001\u6458\u8981\u3001\u8be6\u7ec6\u5206\u6790\u3001\u5efa\u8bae\u7b49\u90e8\u5206\u3002&#034;<\/span><br \/>\n      <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;depends_on&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;analyze&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;timeout&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;30s&#034;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n  <span class=\"token punctuation\">]<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u8fd9\u4e2a\u7f16\u6392\u8ba1\u5212\u7684\u6267\u884c\u6d41\u7a0b\u662f&#xff1a;<\/p>\n<li>\u5e76\u884c\u542f\u52a8&#xff1a;fetch_data&#xff08;\u83b7\u53d6\u8d22\u52a1\u6570\u636e&#xff09;\u548c search_benchmarks&#xff08;\u641c\u7d22\u884c\u4e1a\u57fa\u51c6&#xff09;\u540c\u65f6\u6267\u884c<\/li>\n<li>\u4e32\u884c\u4f9d\u8d56&#xff1a;parse_data&#xff08;\u89e3\u6790\u6570\u636e&#xff09;\u7b49\u5f85 fetch_data \u5b8c\u6210<\/li>\n<li>\u6c47\u805a\u70b9&#xff1a;analyze&#xff08;LLM\u5206\u6790&#xff09;\u7b49\u5f85 parse_data \u548c search_benchmarks \u90fd\u5b8c\u6210<\/li>\n<li>\u5e76\u884c\u540e\u5904\u7406&#xff1a;save_memory&#xff08;\u4fdd\u5b58\u8bb0\u5fc6&#xff09;\u548c generate_report&#xff08;\u751f\u6210\u62a5\u544a&#xff09;\u5728 analyze \u5b8c\u6210\u540e\u5e76\u884c\u6267\u884c<\/li>\n<li>\u6700\u7ec8\u7ed3\u679c&#xff1a;generate_report \u7684\u8f93\u51fa\u4f5c\u4e3a\u6700\u7ec8\u54cd\u5e94\u8fd4\u56de\u7ed9\u7528\u6237<\/li>\n<h3>5.3 \u8bb0\u5fc6\u8c03\u5ea6\u673a\u5236<\/h3>\n<h4>5.3.1 \u8bb0\u5fc6\u5c42\u7ea7\u4e0e\u8c03\u5ea6\u7b56\u7565<\/h4>\n<p>Hermes Agent \u7684\u8bb0\u5fc6\u7cfb\u7edf\u91c7\u7528\u4e09\u5c42\u67b6\u6784&#xff0c;Gateway \u7684\u8bb0\u5fc6\u8c03\u5ea6\u5668\u6839\u636e\u5f53\u524d\u4efb\u52a1\u7684\u610f\u56fe\u548c\u4e0a\u4e0b\u6587&#xff0c;\u51b3\u5b9a\u4f55\u65f6\u3001\u4ece\u54ea\u4e2a\u5c42\u7ea7\u3001\u8bfb\u53d6\u6216\u5199\u5165\u4ec0\u4e48\u8bb0\u5fc6&#xff1a;<\/p>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502                    \u8bb0\u5fc6\u8c03\u5ea6\u67b6\u6784                                         \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510           \u2502<br \/>\n\u2502  \u2502  \u5de5\u4f5c\u8bb0\u5fc6 (Working Memory)                              \u2502           \u2502<br \/>\n\u2502  \u2502  \u00b7 \u5f53\u524d\u4f1a\u8bdd\u4e0a\u4e0b\u6587&#xff08;\u6d88\u606f\u5386\u53f2&#xff09;                              \u2502           \u2502<br \/>\n\u2502  \u2502  \u00b7 \u6d3b\u8dc3\u5de5\u5177\u8c03\u7528\u6808                                        \u2502           \u2502<br \/>\n\u2502  \u2502  \u00b7 \u4e34\u65f6\u53d8\u91cf                                              \u2502           \u2502<br \/>\n\u2502  \u2502  \u5b58\u50a8: Redis (\u70ed\u5b58\u50a8)                                    \u2502           \u2502<br \/>\n\u2502  \u2502  \u5bff\u547d: \u4f1a\u8bdd\u7ea7\u522b                                          \u2502           \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518           \u2502<br \/>\n\u2502                              \u2502                                       \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510           \u2502<br \/>\n\u2502  \u2502  \u77ed\u671f\u8bb0\u5fc6 (Short-term Memory)                           \u2502           \u2502<br \/>\n\u2502  \u2502  \u00b7 \u6700\u8fd1N\u6b21\u4f1a\u8bdd\u7684\u6458\u8981                                     \u2502           \u2502<br \/>\n\u2502  \u2502  \u00b7 \u7528\u6237\u8fd1\u671f\u504f\u597d\u548c\u884c\u4e3a\u6a21\u5f0f                                \u2502           \u2502<br \/>\n\u2502  \u2502  \u00b7 \u4e34\u65f6\u77e5\u8bc6&#xff08;\u641c\u7d22\u7ed3\u679c\u7f13\u5b58\u7b49&#xff09;                             \u2502           \u2502<br \/>\n\u2502  \u2502  \u5b58\u50a8: PostgreSQL &#043; Redis Cache                         \u2502           \u2502<br \/>\n\u2502  \u2502  \u5bff\u547d: 7-30\u5929                                            \u2502           \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518           \u2502<br \/>\n\u2502                              \u2502                                       \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510           \u2502<br \/>\n\u2502  \u2502  \u957f\u671f\u8bb0\u5fc6 (Long-term Memory)                            \u2502           \u2502<br \/>\n\u2502  \u2502  \u00b7 \u7528\u6237\u753b\u50cf&#xff08;\u804c\u4e1a\u3001\u6280\u80fd\u3001\u504f\u597d&#xff09;                            \u2502           \u2502<br \/>\n\u2502  \u2502  \u00b7 \u6301\u4e45\u5316\u77e5\u8bc6&#xff08;\u7528\u6237\u4f20\u6388\u7684\u4e8b\u5b9e\u3001\u51b3\u7b56&#xff09;                       \u2502           \u2502<br \/>\n\u2502  \u2502  \u00b7 \u8bed\u4e49\u5411\u91cf\u7d22\u5f15&#xff08;\u53ef\u68c0\u7d22\u7684\u77e5\u8bc6\u5e93&#xff09;                          \u2502           \u2502<br \/>\n\u2502  \u2502  \u5b58\u50a8: \u5411\u91cf\u6570\u636e\u5e93 &#043; S3 &#043; PostgreSQL                      \u2502           \u2502<br \/>\n\u2502  \u2502  \u5bff\u547d: \u6c38\u4e45&#xff08;\u53ef\u624b\u52a8\u5220\u9664&#xff09;                                 \u2502           \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518           \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<h4>5.3.2 \u8bb0\u5fc6\u8c03\u5ea6\u5668\u5b9e\u73b0<\/h4>\n<p><span class=\"token comment\">\/\/\/ \u8bb0\u5fc6\u8c03\u5ea6\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">MemoryScheduler<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5de5\u4f5c\u8bb0\u5fc6\u5b58\u50a8<\/span><br \/>\n    working_memory<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">WorkingMemoryStore<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u77ed\u671f\u8bb0\u5fc6\u5b58\u50a8<\/span><br \/>\n    short_term_memory<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ShortTermMemoryStore<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u957f\u671f\u8bb0\u5fc6\u5b58\u50a8<\/span><br \/>\n    long_term_memory<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">LongTermMemoryStore<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u8bb0\u5fc6\u68c0\u7d22\u6a21\u578b<\/span><br \/>\n    retrieval_model<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">MemoryRetrievalModel<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u8bb0\u5fc6\u8c03\u5ea6\u51b3\u7b56<\/span><br \/>\n<span class=\"token attribute attr-name\">#[derive(Clone, Debug)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">MemoryDecision<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u662f\u5426\u9700\u8981\u8bfb\u53d6\u5de5\u4f5c\u8bb0\u5fc6<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> read_working<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u662f\u5426\u9700\u8981\u8bfb\u53d6\u77ed\u671f\u8bb0\u5fc6<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> read_short_term<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u662f\u5426\u9700\u8981\u8bfb\u53d6\u957f\u671f\u8bb0\u5fc6<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> read_long_term<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u957f\u671f\u8bb0\u5fc6\u68c0\u7d22\u67e5\u8be2<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> retrieval_query<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u662f\u5426\u9700\u8981\u5199\u5165\u8bb0\u5fc6<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> write_memory<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5199\u5165\u7c7b\u578b<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> write_type<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">MemoryWriteType<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">MemoryWriteType<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4f1a\u8bdd\u6458\u8981&#xff08;\u4f1a\u8bdd\u7ed3\u675f\u65f6&#xff09;<\/span><br \/>\n    <span class=\"token class-name\">SessionSummary<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7528\u6237\u504f\u597d\u66f4\u65b0<\/span><br \/>\n    <span class=\"token class-name\">PreferenceUpdate<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u77e5\u8bc6\u5b58\u50a8<\/span><br \/>\n    <span class=\"token class-name\">KnowledgeStore<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u51b3\u7b56\u8bb0\u5f55<\/span><br \/>\n    <span class=\"token class-name\">DecisionRecord<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">MemoryScheduler<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6839\u636e\u610f\u56fe\u548c\u4e0a\u4e0b\u6587\u51b3\u5b9a\u8bb0\u5fc6\u8c03\u5ea6\u7b56\u7565<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">decide<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        intent<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">IntentDetection<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        context<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">MemoryDecision<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> decision <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">MemoryDecision<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            read_working<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span>  <span class=\"token comment\">\/\/ \u603b\u662f\u8bfb\u53d6\u5de5\u4f5c\u8bb0\u5fc6<\/span><br \/>\n            read_short_term<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            read_long_term<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            retrieval_query<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            write_memory<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            write_type<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">match<\/span> intent<span class=\"token punctuation\">.<\/span>intent<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_str<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token string\">&#034;casual_chat&#034;<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token comment\">\/\/ \u95f2\u804a&#xff1a;\u53ea\u8bfb\u5de5\u4f5c\u8bb0\u5fc6&#xff0c;\u4e0d\u9700\u8981\u957f\u671f\u8bb0\u5fc6<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token string\">&#034;knowledge_query&#034;<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token comment\">\/\/ \u77e5\u8bc6\u67e5\u8be2&#xff1a;\u9700\u8981\u8bfb\u53d6\u957f\u671f\u8bb0\u5fc6<\/span><br \/>\n                decision<span class=\"token punctuation\">.<\/span>read_long_term <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                decision<span class=\"token punctuation\">.<\/span>retrieval_query <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    intent<span class=\"token punctuation\">.<\/span>extracted_params<br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;query&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">cloned<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or_default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token string\">&#034;task_planning&#034;<\/span> <span class=\"token operator\">|<\/span> <span class=\"token string\">&#034;multi_step&#034;<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token comment\">\/\/ \u4efb\u52a1\u89c4\u5212&#xff1a;\u9700\u8981\u77ed\u671f\u8bb0\u5fc6&#xff08;\u4e86\u89e3\u6700\u8fd1\u505a\u8fc7\u4ec0\u4e48&#xff09;<\/span><br \/>\n                decision<span class=\"token punctuation\">.<\/span>read_short_term <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                decision<span class=\"token punctuation\">.<\/span>read_long_term <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                decision<span class=\"token punctuation\">.<\/span>retrieval_query <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">build_retrieval_query<\/span><span class=\"token punctuation\">(<\/span>intent<span class=\"token punctuation\">,<\/span> context<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token string\">&#034;data_analysis&#034;<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token comment\">\/\/ \u6570\u636e\u5206\u6790&#xff1a;\u53ef\u80fd\u9700\u8981\u957f\u671f\u8bb0\u5fc6&#xff08;\u5386\u53f2\u5206\u6790\u7ed3\u679c&#xff09;<\/span><br \/>\n                decision<span class=\"token punctuation\">.<\/span>read_short_term <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                decision<span class=\"token punctuation\">.<\/span>read_long_term <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            _ <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token comment\">\/\/ \u9ed8\u8ba4&#xff1a;\u8bfb\u53d6\u77ed\u671f\u8bb0\u5fc6<\/span><br \/>\n                decision<span class=\"token punctuation\">.<\/span>read_short_term <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u4f1a\u8bdd\u63a5\u8fd1\u7ed3\u675f\u65f6&#xff0c;\u6807\u8bb0\u9700\u8981\u5199\u5165\u8bb0\u5fc6<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> context<span class=\"token punctuation\">.<\/span>metadata<span class=\"token punctuation\">.<\/span>turn_count <span class=\"token operator\">&gt;<\/span> <span class=\"token number\">0<\/span> <span class=\"token operator\">&amp;&amp;<\/span><br \/>\n           context<span class=\"token punctuation\">.<\/span>metadata<span class=\"token punctuation\">.<\/span>turn_count <span class=\"token operator\">%<\/span> <span class=\"token number\">10<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            decision<span class=\"token punctuation\">.<\/span>write_memory <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            decision<span class=\"token punctuation\">.<\/span>write_type <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">MemoryWriteType<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">SessionSummary<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u5982\u679c\u7528\u6237\u8868\u8fbe\u4e86\u504f\u597d&#xff0c;\u6807\u8bb0\u5199\u5165<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">detect_preference_expression<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>intent<span class=\"token punctuation\">,<\/span> context<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            decision<span class=\"token punctuation\">.<\/span>write_memory <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            decision<span class=\"token punctuation\">.<\/span>write_type <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">MemoryWriteType<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">PreferenceUpdate<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        decision<br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u6267\u884c\u8bb0\u5fc6\u8c03\u5ea6<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">execute<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        decision<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">MemoryDecision<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        context<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">MemoryBundle<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">MemoryError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> bundle <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">MemoryBundle<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8bfb\u53d6\u5de5\u4f5c\u8bb0\u5fc6&#xff08;\u603b\u662f\u6267\u884c&#xff09;<\/span><br \/>\n        bundle<span class=\"token punctuation\">.<\/span>working <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>working_memory<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>context<span class=\"token punctuation\">.<\/span>session_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8bfb\u53d6\u77ed\u671f\u8bb0\u5fc6<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> decision<span class=\"token punctuation\">.<\/span>read_short_term <span class=\"token punctuation\">{<\/span><br \/>\n            bundle<span class=\"token punctuation\">.<\/span>short_term <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>short_term_memory<br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">get_recent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>context<span class=\"token punctuation\">.<\/span>user_id<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">from_secs<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">7<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">86400<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><br \/>\n            <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8bfb\u53d6\u957f\u671f\u8bb0\u5fc6<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> decision<span class=\"token punctuation\">.<\/span>read_long_term <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>query<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>decision<span class=\"token punctuation\">.<\/span>retrieval_query <span class=\"token punctuation\">{<\/span><br \/>\n                bundle<span class=\"token punctuation\">.<\/span>long_term <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>long_term_memory<br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">semantic_search<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>context<span class=\"token punctuation\">.<\/span>user_id<span class=\"token punctuation\">,<\/span> query<span class=\"token punctuation\">,<\/span> <span class=\"token number\">10<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><br \/>\n                <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                bundle<span class=\"token punctuation\">.<\/span>long_term <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>long_term_memory<br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">get_user_profile<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>context<span class=\"token punctuation\">.<\/span>user_id<span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><br \/>\n                <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>bundle<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u68c0\u6d4b\u7528\u6237\u662f\u5426\u8868\u8fbe\u4e86\u504f\u597d<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">detect_preference_expression<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        intent<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">IntentDetection<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        _context<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token keyword\">bool<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u7b80\u5316\u7684\u504f\u597d\u68c0\u6d4b\u903b\u8f91<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> preference_keywords <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><br \/>\n            <span class=\"token string\">&#034;\u6211\u559c\u6b22&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;\u6211\u4e0d\u559c\u6b22&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;\u8bf7\u8bb0\u4f4f&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;\u4ee5\u540e\u90fd\u7528&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;I prefer&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;I like&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;remember that&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>text<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> intent<span class=\"token punctuation\">.<\/span>extracted_params<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;text&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> preference_keywords<span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">any<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>kw<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> text<span class=\"token punctuation\">.<\/span><span class=\"token function\">contains<\/span><span class=\"token punctuation\">(<\/span>kw<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token boolean\">false<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">build_retrieval_query<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        intent<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">IntentDetection<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        context<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u57fa\u4e8e\u610f\u56fe\u548c\u6700\u8fd1\u5bf9\u8bdd\u6784\u5efa\u68c0\u7d22\u67e5\u8be2<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> recent_topic <span class=\"token operator\">&#061;<\/span> context<span class=\"token punctuation\">.<\/span>metadata<span class=\"token punctuation\">.<\/span>topic<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_deref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;{} {}&#034;<\/span><span class=\"token punctuation\">,<\/span> recent_topic<span class=\"token punctuation\">,<\/span> intent<span class=\"token punctuation\">.<\/span>intent<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u8bb0\u5fc6\u5305&#xff08;\u5305\u542b\u4ece\u5404\u5c42\u7ea7\u8bfb\u53d6\u7684\u8bb0\u5fc6&#xff09;<\/span><br \/>\n<span class=\"token attribute attr-name\">#[derive(Default, Clone, Debug)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">MemoryBundle<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> working<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">WorkingMemory<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> short_term<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ShortTermMemory<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> long_term<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">LongTermMemory<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>5.3.3 \u8bb0\u5fc6\u6ce8\u5165\u7b56\u7565<\/h4>\n<p>\u8bfb\u53d6\u5230\u7684\u8bb0\u5fc6\u9700\u8981\u4ee5\u9002\u5f53\u7684\u65b9\u5f0f\u6ce8\u5165\u5230 LLM \u7684\u4e0a\u4e0b\u6587\u4e2d&#xff0c;\u65e2\u4e0d\u80fd\u5360\u7528\u8fc7\u591a Token&#xff0c;\u53c8\u8981\u786e\u4fdd\u76f8\u5173\u4fe1\u606f\u88ab\u6709\u6548\u5229\u7528&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u8bb0\u5fc6\u6ce8\u5165\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">MemoryInjector<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ Token \u4f30\u7b97\u5668<\/span><br \/>\n    token_estimator<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">TokenEstimator<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u8bb0\u5fc6 Token \u9884\u7b97&#xff08;\u5360\u4e0a\u4e0b\u6587\u7a97\u53e3\u7684\u6bd4\u4f8b&#xff09;<\/span><br \/>\n    memory_token_budget<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">f64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">MemoryInjector<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5c06\u8bb0\u5fc6\u6ce8\u5165\u5230 LLM \u4e0a\u4e0b\u6587<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">inject<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        messages<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">mut<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Message<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        bundle<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">MemoryBundle<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        context_window<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">InjectionResult<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> tokens_injected <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0u64<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> memory_budget <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span>context_window <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">f64<\/span> <span class=\"token operator\">*<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>memory_token_budget<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> injected_sections <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u6ce8\u5165\u957f\u671f\u8bb0\u5fc6&#xff08;\u7528\u6237\u753b\u50cf&#xff09;<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>lt<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>bundle<span class=\"token punctuation\">.<\/span>long_term <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>profile<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>lt<span class=\"token punctuation\">.<\/span>user_profile <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">let<\/span> section <span class=\"token operator\">&#061;<\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    <span class=\"token string\">&#034;[\u7528\u6237\u753b\u50cf]\\\\n{}\\\\n&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    profile<span class=\"token punctuation\">.<\/span>summary<br \/>\n                <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token keyword\">let<\/span> tokens <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>token_estimator<span class=\"token punctuation\">.<\/span><span class=\"token function\">estimate_text<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>section<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token keyword\">if<\/span> tokens_injected <span class=\"token operator\">&#043;<\/span> tokens <span class=\"token operator\">&lt;&#061;<\/span> memory_budget <span class=\"token punctuation\">{<\/span><br \/>\n                    injected_sections<span class=\"token punctuation\">.<\/span><span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span>section<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    tokens_injected <span class=\"token operator\">&#043;&#061;<\/span> tokens<span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u6ce8\u5165\u76f8\u5173\u957f\u671f\u8bb0\u5fc6<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>memories<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>lt<span class=\"token punctuation\">.<\/span>relevant_memories <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">let<\/span> section <span class=\"token operator\">&#061;<\/span> memories<span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">take<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">5<\/span><span class=\"token punctuation\">)<\/span>  <span class=\"token comment\">\/\/ \u6700\u591a5\u6761<\/span><br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>m<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;- {}&#034;<\/span><span class=\"token punctuation\">,<\/span> m<span class=\"token punctuation\">.<\/span>summary<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">::<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span>_<span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">join<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\\\\n&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token keyword\">let<\/span> section <span class=\"token operator\">&#061;<\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;[\u76f8\u5173\u8bb0\u5fc6]\\\\n{}\\\\n&#034;<\/span><span class=\"token punctuation\">,<\/span> section<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token keyword\">let<\/span> tokens <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>token_estimator<span class=\"token punctuation\">.<\/span><span class=\"token function\">estimate_text<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>section<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token keyword\">if<\/span> tokens_injected <span class=\"token operator\">&#043;<\/span> tokens <span class=\"token operator\">&lt;&#061;<\/span> memory_budget <span class=\"token punctuation\">{<\/span><br \/>\n                    injected_sections<span class=\"token punctuation\">.<\/span><span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span>section<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    tokens_injected <span class=\"token operator\">&#043;&#061;<\/span> tokens<span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u6ce8\u5165\u77ed\u671f\u8bb0\u5fc6<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>st<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>bundle<span class=\"token punctuation\">.<\/span>short_term <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> section <span class=\"token operator\">&#061;<\/span> st<span class=\"token punctuation\">.<\/span>recent_summaries<span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">take<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">3<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>s<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;- [{}] {}&#034;<\/span><span class=\"token punctuation\">,<\/span> s<span class=\"token punctuation\">.<\/span>timestamp<span class=\"token punctuation\">.<\/span><span class=\"token function\">format<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;%m-%d&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> s<span class=\"token punctuation\">.<\/span>summary<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">::<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span>_<span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">join<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\\\\n&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> section <span class=\"token operator\">&#061;<\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;[\u8fd1\u671f\u4f1a\u8bdd\u6458\u8981]\\\\n{}\\\\n&#034;<\/span><span class=\"token punctuation\">,<\/span> section<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> tokens <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>token_estimator<span class=\"token punctuation\">.<\/span><span class=\"token function\">estimate_text<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>section<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> tokens_injected <span class=\"token operator\">&#043;<\/span> tokens <span class=\"token operator\">&lt;&#061;<\/span> memory_budget <span class=\"token punctuation\">{<\/span><br \/>\n                injected_sections<span class=\"token punctuation\">.<\/span><span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span>section<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                tokens_injected <span class=\"token operator\">&#043;&#061;<\/span> tokens<span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u5c06\u8bb0\u5fc6\u6ce8\u5165\u4e3a\u7cfb\u7edf\u6d88\u606f<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token operator\">!<\/span>injected_sections<span class=\"token punctuation\">.<\/span><span class=\"token function\">is_empty<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> memory_block <span class=\"token operator\">&#061;<\/span> injected_sections<span class=\"token punctuation\">.<\/span><span class=\"token function\">join<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\\\\n&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> system_msg <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Message<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">system<\/span><span class=\"token punctuation\">(<\/span><span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                <span class=\"token string\">&#034;\u4ee5\u4e0b\u662f\u5173\u4e8e\u7528\u6237\u7684\u76f8\u5173\u8bb0\u5fc6\u4fe1\u606f&#xff0c;\u8bf7\u53c2\u8003&#xff1a;\\\\n\\\\n{}\\\\n&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                memory_block<br \/>\n            <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u63d2\u5165\u5230\u6d88\u606f\u5217\u8868\u5f00\u5934&#xff08;\u5728\u539f\u59cb\u7cfb\u7edf\u63d0\u793a\u4e4b\u540e&#xff09;<\/span><br \/>\n            messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">insert<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> system_msg<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token class-name\">InjectionResult<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            tokens_injected<span class=\"token punctuation\">,<\/span><br \/>\n            sections_injected<span class=\"token punctuation\">:<\/span> injected_sections<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h3>5.4 \u5b89\u5168\u6c99\u7bb1\u96c6\u6210<\/h3>\n<h4>5.4.1 \u6c99\u7bb1\u67b6\u6784<\/h4>\n<p>\u5bf9\u4e8e\u4ee3\u7801\u6267\u884c\u7b49\u9ad8\u98ce\u9669\u5de5\u5177\u8c03\u7528&#xff0c;Gateway \u901a\u8fc7\u5b89\u5168\u6c99\u7bb1\u63d0\u4f9b\u9694\u79bb\u6267\u884c\u73af\u5883\u3002Hermes Agent \u9009\u62e9 Firecracker microVM \u4f5c\u4e3a\u6c99\u7bb1\u5f15\u64ce&#xff1a;<\/p>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502                    \u5b89\u5168\u6c99\u7bb1\u67b6\u6784                                         \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u2502<br \/>\n\u2502  \u2502                     Gateway \u8fdb\u7a0b                                \u2502   \u2502<br \/>\n\u2502  \u2502                                                               \u2502   \u2502<br \/>\n\u2502  \u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510     \u2502   \u2502<br \/>\n\u2502  \u2502  \u2502 Tool Call 1  \u2502   \u2502 Tool Call 2  \u2502   \u2502 Tool Call 3  \u2502     \u2502   \u2502<br \/>\n\u2502  \u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518     \u2502   \u2502<br \/>\n\u2502  \u2502         \u2502                  \u2502                  \u2502              \u2502   \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518   \u2502<br \/>\n\u2502            \u2502                  \u2502                  \u2502                  \u2502<br \/>\n\u2502            v                  v                  v                  \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510            \u2502<br \/>\n\u2502  \u2502  microVM 1   \u2502   \u2502  microVM 2   \u2502   \u2502  microVM 3   \u2502            \u2502<br \/>\n\u2502  \u2502              \u2502   \u2502              \u2502   \u2502              \u2502            \u2502<br \/>\n\u2502  \u2502 \u00b7 Python     \u2502   \u2502 \u00b7 Node.js    \u2502   \u2502 \u00b7 Shell      \u2502            \u2502<br \/>\n\u2502  \u2502 \u00b7 \u5185\u5b58:512MB \u2502   \u2502 \u00b7 \u5185\u5b58:256MB \u2502   \u2502 \u00b7 \u5185\u5b58:128MB \u2502            \u2502<br \/>\n\u2502  \u2502 \u00b7 CPU: 1\u6838   \u2502   \u2502 \u00b7 CPU: 0.5\u6838 \u2502   \u2502 \u00b7 CPU: 0.25\u6838\u2502            \u2502<br \/>\n\u2502  \u2502 \u00b7 \u65e0\u7f51\u7edc     \u2502   \u2502 \u00b7 \u53d7\u9650\u7f51\u7edc   \u2502   \u2502 \u00b7 \u65e0\u7f51\u7edc     \u2502            \u2502<br \/>\n\u2502  \u2502 \u00b7 \u53ea\u8bfbFS     \u2502   \u2502 \u00b7 \u4e34\u65f6FS     \u2502   \u2502 \u00b7 \u53ea\u8bfbFS     \u2502            \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518            \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u5b89\u5168\u9694\u79bb: \u8fdb\u7a0b\u9694\u79bb &#043; \u6587\u4ef6\u7cfb\u7edf\u9694\u79bb &#043; \u7f51\u7edc\u9694\u79bb &#043; \u8d44\u6e90\u9650\u5236               \u2502<br \/>\n\u2502  \u542f\u52a8\u5ef6\u8fdf: ~125ms (Firecracker microVM)                              \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<h4>5.4.2 \u6c99\u7bb1\u7ba1\u7406\u5668<\/h4>\n<p><span class=\"token comment\">\/\/\/ \u6c99\u7bb1\u7ba1\u7406\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">SandboxManager<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ Firecracker API \u5ba2\u6237\u7aef<\/span><br \/>\n    fc_client<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">FirecrackerClient<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6c99\u7bb1\u6c60&#xff08;\u9884\u70ed\u5b9e\u4f8b&#xff09;<\/span><br \/>\n    pool<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SandboxInstance<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6d3b\u8dc3\u5b9e\u4f8b\u6620\u5c04<\/span><br \/>\n    active<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">SandboxInstance<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u914d\u7f6e<\/span><br \/>\n    config<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">SandboxConfig<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">SandboxInstance<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> sandbox_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> vm_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> status<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">SandboxStatus<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> created_at<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">DateTime<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> socket_path<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> resources<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ResourceLimits<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> network_policy<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">NetworkPolicy<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug, PartialEq, Eq)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">SandboxStatus<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Idle<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">Busy<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">Stopping<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">Stopped<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token class-name\">Failed<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ResourceLimits<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> memory_mb<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u32<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> cpu_cores<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">f32<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> disk_mb<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u32<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> timeout<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">NetworkPolicy<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> mode<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">NetworkMode<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> allowed_domains<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> blocked_ips<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">NetworkMode<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span>        <span class=\"token comment\">\/\/ \u65e0\u7f51\u7edc<\/span><br \/>\n    <span class=\"token class-name\">Restricted<\/span><span class=\"token punctuation\">,<\/span>  <span class=\"token comment\">\/\/ \u53d7\u9650\u7f51\u7edc&#xff08;\u767d\u540d\u5355&#xff09;<\/span><br \/>\n    <span class=\"token class-name\">Full<\/span><span class=\"token punctuation\">,<\/span>        <span class=\"token comment\">\/\/ \u5b8c\u5168\u7f51\u7edc&#xff08;\u4e0d\u63a8\u8350&#xff09;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">SandboxManager<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u83b7\u53d6\u6216\u521b\u5efa\u6c99\u7bb1\u5b9e\u4f8b<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">acquire_or_create<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        session_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SandboxHandle<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">SandboxError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ 1. \u5c1d\u8bd5\u4ece\u6c60\u4e2d\u83b7\u53d6\u7a7a\u95f2\u5b9e\u4f8b<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>instance<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">try_acquire_from_pool<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">SandboxHandle<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                instance<span class=\"token punctuation\">,<\/span><br \/>\n                manager<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 2. \u6c60\u4e2d\u6ca1\u6709&#xff0c;\u521b\u5efa\u65b0\u5b9e\u4f8b<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> instance <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">create_sandbox<\/span><span class=\"token punctuation\">(<\/span>session_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">SandboxHandle<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            instance<span class=\"token punctuation\">,<\/span><br \/>\n            manager<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u521b\u5efa\u65b0\u7684\u6c99\u7bb1\u5b9e\u4f8b<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">create_sandbox<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        session_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SandboxInstance<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">SandboxError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> vm_id <span class=\"token operator\">&#061;<\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;vm-{}-{}&#034;<\/span><span class=\"token punctuation\">,<\/span> session_id<span class=\"token punctuation\">,<\/span> <span class=\"token namespace\">uuid<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Uuid<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new_v4<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> socket_path <span class=\"token operator\">&#061;<\/span> <span class=\"token macro property\">format!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/tmp\/{}.sock&#034;<\/span><span class=\"token punctuation\">,<\/span> vm_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ Firecracker VM \u914d\u7f6e<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> vm_config <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">FirecrackerVmConfig<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            vm_id<span class=\"token punctuation\">:<\/span> vm_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            kernel_image<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>config<span class=\"token punctuation\">.<\/span>kernel_image<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            rootfs<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>config<span class=\"token punctuation\">.<\/span>rootfs<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            memory_mib<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>config<span class=\"token punctuation\">.<\/span>default_memory_mb<span class=\"token punctuation\">,<\/span><br \/>\n            vcpu_count<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>config<span class=\"token punctuation\">.<\/span>default_vcpu_count<span class=\"token punctuation\">,<\/span><br \/>\n            network_interfaces<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            drives<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            socket_path<span class=\"token punctuation\">:<\/span> socket_path<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u542f\u52a8 microVM<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>fc_client<span class=\"token punctuation\">.<\/span><span class=\"token function\">create_vm<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>vm_config<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u7b49\u5f85 VM \u5c31\u7eea<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">wait_for_ready<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>socket_path<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">from_secs<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">5<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> instance <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">SandboxInstance<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            sandbox_id<span class=\"token punctuation\">:<\/span> <span class=\"token namespace\">uuid<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Uuid<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new_v4<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">to_string<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            vm_id<span class=\"token punctuation\">,<\/span><br \/>\n            status<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">SandboxStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Busy<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            created_at<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Utc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            socket_path<span class=\"token punctuation\">,<\/span><br \/>\n            resources<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ResourceLimits<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                memory_mb<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>config<span class=\"token punctuation\">.<\/span>default_memory_mb<span class=\"token punctuation\">,<\/span><br \/>\n                cpu_cores<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>config<span class=\"token punctuation\">.<\/span>default_vcpu_count <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">f32<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                disk_mb<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>config<span class=\"token punctuation\">.<\/span>default_disk_mb<span class=\"token punctuation\">,<\/span><br \/>\n                timeout<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>config<span class=\"token punctuation\">.<\/span>default_timeout<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            network_policy<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">NetworkPolicy<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                mode<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">NetworkMode<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                allowed_domains<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                blocked_ips<span class=\"token punctuation\">:<\/span> <span class=\"token macro property\">vec!<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8bb0\u5f55\u6d3b\u8dc3\u5b9e\u4f8b<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>active<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">insert<\/span><span class=\"token punctuation\">(<\/span>instance<span class=\"token punctuation\">.<\/span>sandbox_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> instance<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span>instance<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u5728\u6c99\u7bb1\u4e2d\u6267\u884c\u4ee3\u7801<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">execute_code<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        sandbox<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SandboxInstance<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        language<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        code<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ExecutionResult<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">SandboxError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> start <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Instant<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u901a\u8fc7 VSOCK \u6216 HTTP \u5411\u6c99\u7bb1\u53d1\u9001\u6267\u884c\u8bf7\u6c42<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> request <span class=\"token operator\">&#061;<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">json!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token string\">&#034;language&#034;<\/span><span class=\"token punctuation\">:<\/span> language<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;code&#034;<\/span><span class=\"token punctuation\">:<\/span> code<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;timeout&#034;<\/span><span class=\"token punctuation\">:<\/span> sandbox<span class=\"token punctuation\">.<\/span>resources<span class=\"token punctuation\">.<\/span>timeout<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_secs<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> response <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>fc_client<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">execute_in_vm<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>sandbox<span class=\"token punctuation\">.<\/span>vm_id<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span>request<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> execution_time <span class=\"token operator\">&#061;<\/span> start<span class=\"token punctuation\">.<\/span><span class=\"token function\">elapsed<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ExecutionResult<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            stdout<span class=\"token punctuation\">:<\/span> response<span class=\"token punctuation\">.<\/span>stdout<span class=\"token punctuation\">,<\/span><br \/>\n            stderr<span class=\"token punctuation\">:<\/span> response<span class=\"token punctuation\">.<\/span>stderr<span class=\"token punctuation\">,<\/span><br \/>\n            exit_code<span class=\"token punctuation\">:<\/span> response<span class=\"token punctuation\">.<\/span>exit_code<span class=\"token punctuation\">,<\/span><br \/>\n            execution_time_ms<span class=\"token punctuation\">:<\/span> execution_time<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_millis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            tokens_used<span class=\"token punctuation\">:<\/span> response<span class=\"token punctuation\">.<\/span>tokens_used<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u91ca\u653e\u6c99\u7bb1&#xff08;\u5f52\u8fd8\u6c60\u6216\u9500\u6bc1&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">release<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> sandbox_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">str<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">SandboxError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> active <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>active<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">mut<\/span> instance<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> active<span class=\"token punctuation\">.<\/span><span class=\"token function\">remove<\/span><span class=\"token punctuation\">(<\/span>sandbox_id<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token comment\">\/\/ \u5982\u679c\u6c60\u672a\u6ee1&#xff0c;\u5f52\u8fd8\u6c60\u4e2d\u590d\u7528<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> pool <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>pool<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> pool<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&lt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>config<span class=\"token punctuation\">.<\/span>pool_size <span class=\"token punctuation\">{<\/span><br \/>\n                instance<span class=\"token punctuation\">.<\/span>status <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">SandboxStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Idle<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                pool<span class=\"token punctuation\">.<\/span><span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span>instance<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token comment\">\/\/ \u6c60\u5df2\u6ee1&#xff0c;\u9500\u6bc1\u5b9e\u4f8b<\/span><br \/>\n                <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">destroy_sandbox<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>instance<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u9500\u6bc1\u6c99\u7bb1\u5b9e\u4f8b<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">destroy_sandbox<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        instance<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">SandboxInstance<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">SandboxError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>fc_client<span class=\"token punctuation\">.<\/span><span class=\"token function\">destroy_vm<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>instance<span class=\"token punctuation\">.<\/span>vm_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u6e05\u7406\u4e34\u65f6\u6587\u4ef6<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> _ <span class=\"token operator\">&#061;<\/span> <span class=\"token namespace\">std<span class=\"token punctuation\">::<\/span>fs<span class=\"token punctuation\">::<\/span><\/span><span class=\"token function\">remove_file<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>instance<span class=\"token punctuation\">.<\/span>socket_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u5065\u5eb7\u68c0\u67e5<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">health_check<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">ToolError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> pool <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>pool<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> active <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>active<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u7684\u6c99\u7bb1\u5b9e\u4f8b<\/span><br \/>\n        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>pool<span class=\"token punctuation\">.<\/span><span class=\"token function\">is_empty<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">||<\/span> <span class=\"token operator\">!<\/span>active<span class=\"token punctuation\">.<\/span><span class=\"token function\">is_empty<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u6c99\u7bb1\u914d\u7f6e<\/span><br \/>\n<span class=\"token attribute attr-name\">#[derive(Clone, Debug)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">SandboxConfig<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> kernel_image<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> rootfs<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> default_memory_mb<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u32<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> default_vcpu_count<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u32<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> default_disk_mb<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u32<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> default_timeout<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> pool_size<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> pool_warm_count<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>5.4.3 \u6c99\u7bb1\u5b89\u5168\u7b56\u7565<\/h4>\n<p><span class=\"token comment\"># \u6c99\u7bb1\u5b89\u5168\u914d\u7f6e<\/span><br \/>\n<span class=\"token key atrule\">sandbox<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token key atrule\">engine<\/span><span class=\"token punctuation\">:<\/span> firecracker<br \/>\n  <span class=\"token key atrule\">kernel_image<\/span><span class=\"token punctuation\">:<\/span> \/opt\/hermes\/vmlinux<br \/>\n  <span class=\"token key atrule\">rootfs<\/span><span class=\"token punctuation\">:<\/span> \/opt\/hermes\/rootfs.ext4<\/p>\n<p>  <span class=\"token key atrule\">defaults<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">memory_mb<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">512<\/span><br \/>\n    <span class=\"token key atrule\">vcpu_count<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token key atrule\">disk_mb<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1024<\/span><br \/>\n    <span class=\"token key atrule\">timeout<\/span><span class=\"token punctuation\">:<\/span> 30s<\/p>\n<p>  <span class=\"token key atrule\">pool<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">size<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">20<\/span>            <span class=\"token comment\"># \u6c60\u6700\u5927\u5b9e\u4f8b\u6570<\/span><br \/>\n    <span class=\"token key atrule\">warm_count<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">5<\/span>       <span class=\"token comment\"># \u9884\u70ed\u5b9e\u4f8b\u6570<\/span><br \/>\n    <span class=\"token key atrule\">idle_timeout<\/span><span class=\"token punctuation\">:<\/span> 300s  <span class=\"token comment\"># \u7a7a\u95f2\u5b9e\u4f8b\u8d85\u65f6\u56de\u6536<\/span><\/p>\n<p>  <span class=\"token key atrule\">security<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token comment\"># \u6587\u4ef6\u7cfb\u7edf\u5b89\u5168<\/span><br \/>\n    <span class=\"token key atrule\">filesystem<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">mode<\/span><span class=\"token punctuation\">:<\/span> read_only_overlay  <span class=\"token comment\"># \u53ea\u8bfb\u6839 &#043; \u53ef\u5199\u4e34\u65f6\u5c42<\/span><br \/>\n      <span class=\"token key atrule\">temp_dir_size<\/span><span class=\"token punctuation\">:<\/span> 256MB<br \/>\n      <span class=\"token key atrule\">allowed_paths<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> \/tmp<br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> \/workspace<br \/>\n      <span class=\"token key atrule\">blocked_paths<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> \/etc\/shadow<br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> \/root<\/p>\n<p>    <span class=\"token comment\"># \u7f51\u7edc\u5b89\u5168<\/span><br \/>\n    <span class=\"token key atrule\">network<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">default_mode<\/span><span class=\"token punctuation\">:<\/span> none  <span class=\"token comment\"># \u9ed8\u8ba4\u65e0\u7f51\u7edc<\/span><br \/>\n      <span class=\"token key atrule\">restricted<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token key atrule\">allowed_domains<\/span><span class=\"token punctuation\">:<\/span><br \/>\n          <span class=\"token punctuation\">&#8211;<\/span> pypi.org<br \/>\n          <span class=\"token punctuation\">&#8211;<\/span> files.pythonhosted.org<br \/>\n          <span class=\"token punctuation\">&#8211;<\/span> registry.npmjs.org<br \/>\n        <span class=\"token key atrule\">blocked_ips<\/span><span class=\"token punctuation\">:<\/span><br \/>\n          <span class=\"token punctuation\">&#8211;<\/span> 10.0.0.0\/8<br \/>\n          <span class=\"token punctuation\">&#8211;<\/span> 172.16.0.0\/12<br \/>\n          <span class=\"token punctuation\">&#8211;<\/span> 192.168.0.0\/16<br \/>\n        <span class=\"token key atrule\">max_connections<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">10<\/span><br \/>\n        <span class=\"token key atrule\">connection_timeout<\/span><span class=\"token punctuation\">:<\/span> 10s<\/p>\n<p>    <span class=\"token comment\"># \u8d44\u6e90\u9650\u5236<\/span><br \/>\n    <span class=\"token key atrule\">resources<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">max_processes<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">50<\/span><br \/>\n      <span class=\"token key atrule\">max_file_descriptors<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">256<\/span><br \/>\n      <span class=\"token key atrule\">max_memory_mb<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1024<\/span><br \/>\n      <span class=\"token key atrule\">max_cpu_time<\/span><span class=\"token punctuation\">:<\/span> 60s<\/p>\n<p>    <span class=\"token comment\"># \u7cfb\u7edf\u8c03\u7528\u8fc7\u6ee4<\/span><br \/>\n    <span class=\"token key atrule\">syscall_filter<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">enabled<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><br \/>\n      <span class=\"token key atrule\">mode<\/span><span class=\"token punctuation\">:<\/span> whitelist<br \/>\n      <span class=\"token key atrule\">allowed_syscalls<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> read<br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> write<br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> open<br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> close<br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> mmap<br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> munmap<br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> brk<br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> exit<br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> exit_group<br \/>\n        <span class=\"token comment\"># &#8230; \u66f4\u591a\u5141\u8bb8\u7684\u7cfb\u7edf\u8c03\u7528<\/span><\/p>\n<p>    <span class=\"token comment\"># \u73af\u5883\u53d8\u91cf\u8fc7\u6ee4<\/span><br \/>\n    <span class=\"token key atrule\">env_filter<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">blocked_prefixes<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> SECRET_<br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> PRIVATE_<br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> KEY_<br \/>\n      <span class=\"token key atrule\">blocked_names<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> AWS_ACCESS_KEY_ID<br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> AWS_SECRET_ACCESS_KEY<br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> DATABASE_URL<\/p>\n<hr \/>\n<h2>\u7b2c\u516d\u7ae0 Gateway \u4e0e\u5176\u4ed6\u6a21\u5757\u7684\u4ea4\u4e92<\/h2>\n<h3>6.1 \u4e0e\u8bb0\u5fc6\u7cfb\u7edf\u7684\u534f\u4f5c<\/h3>\n<h4>6.1.1 \u4ea4\u4e92\u67b6\u6784<\/h4>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502               Gateway \u4e0e\u8bb0\u5fc6\u7cfb\u7edf\u7684\u534f\u4f5c\u67b6\u6784                               \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510         \u2502<br \/>\n\u2502  \u2502             \u2502  1.\u8bb0\u5fc6\u8c03\u5ea6\u51b3\u7b56      \u2502                     \u2502         \u2502<br \/>\n\u2502  \u2502   Gateway   \u2502 \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550&gt; \u2502                     \u2502         \u2502<br \/>\n\u2502  \u2502  \u8def\u7531\u5f15\u64ce    \u2502                    \u2502   \u8bb0\u5fc6\u7cfb\u7edf            \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502  2.\u8bfb\u53d6\u5de5\u4f5c\u8bb0\u5fc6      \u2502  (Memory System)    \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502 &lt;\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 \u2502                     \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502                    \u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502  3.\u68c0\u7d22\u957f\u671f\u8bb0\u5fc6      \u2502  \u2502 Working Memory\u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502 \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550&gt; \u2502  \u2502 (Redis)       \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502                    \u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502  4.\u8fd4\u56de\u76f8\u5173\u8bb0\u5fc6      \u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502 &lt;\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 \u2502  \u2502 Short-term    \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502                    \u2502  \u2502 (PostgreSQL)  \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502  5.\u8bb0\u5fc6\u6ce8\u5165\u4e0a\u4e0b\u6587    \u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502 (\u5185\u90e8\u64cd\u4f5c)          \u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502                    \u2502  \u2502 Long-term     \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502  6.\u6267\u884c\u4efb\u52a1         \u2502  \u2502 (Vector DB)   \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502 (\u5185\u90e8\u64cd\u4f5c)          \u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502                    \u2502                     \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502  7.\u5199\u5165\u65b0\u8bb0\u5fc6        \u2502                     \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502 \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550&gt; \u2502                     \u2502         \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518         \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<h4>6.1.2 \u4ea4\u4e92\u534f\u8bae<\/h4>\n<p>Gateway \u4e0e\u8bb0\u5fc6\u7cfb\u7edf\u4e4b\u95f4\u901a\u8fc7 gRPC \u8fdb\u884c\u901a\u4fe1&#xff0c;\u5b9a\u4e49\u4e86\u4ee5\u4e0b\u6838\u5fc3 RPC \u63a5\u53e3&#xff1a;<\/p>\n<p>\/\/ memory_service.proto<br \/>\nsyntax &#061; &#034;proto3&#034;;<\/p>\n<p>package hermes.memory;<\/p>\n<p>service MemoryService {<br \/>\n    \/\/ \u8bfb\u53d6\u5de5\u4f5c\u8bb0\u5fc6<br \/>\n    rpc GetWorkingMemory(GetWorkingMemoryRequest) returns (WorkingMemory);<\/p>\n<p>    \/\/ \u68c0\u7d22\u957f\u671f\u8bb0\u5fc6<br \/>\n    rpc SearchLongTermMemory(SearchRequest) returns (SearchResponse);<\/p>\n<p>    \/\/ \u83b7\u53d6\u7528\u6237\u753b\u50cf<br \/>\n    rpc GetUserProfile(GetUserProfileRequest) returns (UserProfile);<\/p>\n<p>    \/\/ \u5199\u5165\u8bb0\u5fc6<br \/>\n    rpc WriteMemory(WriteMemoryRequest) returns (WriteMemoryResponse);<\/p>\n<p>    \/\/ \u66f4\u65b0\u7528\u6237\u753b\u50cf<br \/>\n    rpc UpdateUserProfile(UpdateUserProfileRequest) returns (UserProfile);<\/p>\n<p>    \/\/ \u83b7\u53d6\u6700\u8fd1\u4f1a\u8bdd\u6458\u8981<br \/>\n    rpc GetRecentSummaries(GetRecentSummariesRequest) returns (RecentSummaries);<\/p>\n<p>    \/\/ \u8bb0\u5fc6\u5065\u5eb7\u68c0\u67e5<br \/>\n    rpc HealthCheck(HealthCheckRequest) returns (HealthCheckResponse);<br \/>\n}<\/p>\n<p>message GetWorkingMemoryRequest {<br \/>\n    string session_id &#061; 1;<br \/>\n}<\/p>\n<p>message WorkingMemory {<br \/>\n    string session_id &#061; 1;<br \/>\n    repeated Message messages &#061; 2;<br \/>\n    optional string compressed_summary &#061; 3;<br \/>\n    map&lt;string, string&gt; temp_variables &#061; 4;<br \/>\n}<\/p>\n<p>message SearchRequest {<br \/>\n    string user_id &#061; 1;<br \/>\n    string query &#061; 2;<br \/>\n    int32 top_k &#061; 3;<br \/>\n    float min_score &#061; 4;<br \/>\n    repeated string memory_types &#061; 5;<br \/>\n}<\/p>\n<p>message SearchResponse {<br \/>\n    repeated MemoryItem items &#061; 1;<br \/>\n}<\/p>\n<p>message MemoryItem {<br \/>\n    string memory_id &#061; 1;<br \/>\n    string content &#061; 2;<br \/>\n    float relevance_score &#061; 3;<br \/>\n    string memory_type &#061; 4;<br \/>\n    int64 created_at &#061; 5;<br \/>\n    map&lt;string, string&gt; metadata &#061; 6;<br \/>\n}<\/p>\n<p>message WriteMemoryRequest {<br \/>\n    string user_id &#061; 1;<br \/>\n    string session_id &#061; 2;<br \/>\n    string content &#061; 3;<br \/>\n    string memory_type &#061; 4;<br \/>\n    map&lt;string, string&gt; metadata &#061; 5;<br \/>\n    bool enable_dedup &#061; 6;<br \/>\n}<\/p>\n<p>message WriteMemoryResponse {<br \/>\n    string memory_id &#061; 1;<br \/>\n    bool is_duplicate &#061; 2;<br \/>\n}<\/p>\n<h4>6.1.3 \u964d\u7ea7\u7b56\u7565<\/h4>\n<p>\u5f53\u8bb0\u5fc6\u7cfb\u7edf\u4e0d\u53ef\u7528\u65f6&#xff0c;Gateway \u7684\u964d\u7ea7\u884c\u4e3a&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u8bb0\u5fc6\u7cfb\u7edf\u964d\u7ea7\u5904\u7406\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">MemoryDegradationHandler<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">MemoryDegradationHandler<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">handle_memory_unavailable<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        context<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">mut<\/span> <span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">MemoryBundle<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token namespace\">tracing<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">warn!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token string\">&#034;Memory system unavailable, degrading to stateless mode&#034;<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u964d\u7ea7\u4e3a\u65e0\u8bb0\u5fc6\u6a21\u5f0f<\/span><br \/>\n        <span class=\"token comment\">\/\/ 1. \u5de5\u4f5c\u8bb0\u5fc6&#xff1a;\u4ecd\u7136\u53ef\u7528&#xff08;\u6765\u81ea\u672c\u5730\u7f13\u5b58&#xff09;<\/span><br \/>\n        <span class=\"token comment\">\/\/ 2. \u77ed\u671f\u8bb0\u5fc6&#xff1a;\u8df3\u8fc7<\/span><br \/>\n        <span class=\"token comment\">\/\/ 3. \u957f\u671f\u8bb0\u5fc6&#xff1a;\u8df3\u8fc7<\/span><\/p>\n<p>        <span class=\"token class-name\">MemoryBundle<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            working<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">WorkingMemory<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                session_id<span class=\"token punctuation\">:<\/span> context<span class=\"token punctuation\">.<\/span>session_id<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                messages<span class=\"token punctuation\">:<\/span> context<span class=\"token punctuation\">.<\/span>messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                compressed_summary<span class=\"token punctuation\">:<\/span> context<span class=\"token punctuation\">.<\/span>compressed_summary<br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">as_ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>s<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> s<span class=\"token punctuation\">.<\/span>text<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                temp_variables<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">HashMap<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            short_term<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            long_term<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">handle_memory_timeout<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        partial_result<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">PartialMemoryBundle<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">MemoryBundle<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u4f7f\u7528\u5df2\u83b7\u53d6\u7684\u90e8\u5206\u7ed3\u679c&#xff0c;\u7f3a\u5931\u90e8\u5206\u7528\u7a7a\u503c\u586b\u5145<\/span><br \/>\n        <span class=\"token namespace\">tracing<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">warn!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token string\">&#034;Memory system timeout, using partial results&#034;<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">MemoryBundle<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            working<span class=\"token punctuation\">:<\/span> partial_result<span class=\"token punctuation\">.<\/span>working<span class=\"token punctuation\">,<\/span><br \/>\n            short_term<span class=\"token punctuation\">:<\/span> partial_result<span class=\"token punctuation\">.<\/span>short_term<span class=\"token punctuation\">,<\/span><br \/>\n            long_term<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">None<\/span><span class=\"token punctuation\">,<\/span>  <span class=\"token comment\">\/\/ \u957f\u671f\u8bb0\u5fc6\u901a\u5e38\u6700\u6162&#xff0c;\u8d85\u65f6\u6982\u7387\u6700\u9ad8<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h3>6.2 \u4e0e\u6a21\u578b\u8def\u7531\u5668\u7684\u534f\u4f5c<\/h3>\n<h4>6.2.1 \u4ea4\u4e92\u67b6\u6784<\/h4>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502            Gateway \u4e0e\u6a21\u578b\u8def\u7531\u5668\u7684\u534f\u4f5c\u67b6\u6784                                \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510         \u2502<br \/>\n\u2502  \u2502             \u2502  1.\u63a8\u7406\u8bf7\u6c42         \u2502                     \u2502         \u2502<br \/>\n\u2502  \u2502   Gateway   \u2502 \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550&gt; \u2502                     \u2502         \u2502<br \/>\n\u2502  \u2502  \u8def\u7531\u5f15\u64ce    \u2502  (model_hint,      \u2502   \u6a21\u578b\u8def\u7531\u5668          \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502   messages,        \u2502  (Model Router)     \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502   constraints)     \u2502                     \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502                    \u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502  2.\u6a21\u578b\u9009\u62e9         \u2502  \u2502 \u8def\u7531\u51b3\u7b56\u5f15\u64ce   \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502 &lt;\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 \u2502  \u2502 \u00b7 \u80fd\u529b\u5339\u914d     \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502  (selected_model)  \u2502  \u2502 \u00b7 \u6210\u672c\u4f18\u5316     \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502                    \u2502  \u2502 \u00b7 \u5ef6\u8fdf\u4f18\u5148     \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502  3.\u63a8\u7406\u6267\u884c         \u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502 \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550&gt; \u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502                    \u2502  \u2502 \u6a21\u578b\u6c60         \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502  4.\u6d41\u5f0f\u54cd\u5e94         \u2502  \u2502 \u00b7 GPT-4o      \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502 &lt;\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 \u2502  \u2502 \u00b7 Claude 3.5  \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502  (token by token)  \u2502  \u2502 \u00b7 Gemini 1.5  \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502                    \u2502  \u2502 \u00b7 \u672c\u5730\u6a21\u578b     \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502  5.\u4f7f\u7528\u7edf\u8ba1         \u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502 &lt;\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 \u2502                     \u2502         \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518         \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<h4>6.2.2 \u6a21\u578b\u9009\u62e9\u7b56\u7565<\/h4>\n<p>Gateway \u5728\u5411\u6a21\u578b\u8def\u7531\u5668\u53d1\u8d77\u8bf7\u6c42\u65f6&#xff0c;\u4f1a\u9644\u5e26\u6a21\u578b\u9009\u62e9\u63d0\u793a&#xff0c;\u5e2e\u52a9\u8def\u7531\u5668\u505a\u51fa\u6700\u4f18\u51b3\u7b56&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u6a21\u578b\u8bf7\u6c42<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ModelRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6a21\u578b\u63d0\u793a&#xff08;\u975e\u5f3a\u5236\u6307\u5b9a&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> model<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ModelHint<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6d88\u606f\u5217\u8868<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> messages<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Message<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6e29\u5ea6<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> temperature<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">f32<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6700\u5927Token\u6570<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> max_tokens<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u32<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4f18\u5148\u7ea7<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> priority<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">RequestPriority<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7ea6\u675f\u6761\u4ef6<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> constraints<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ModelConstraints<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u6a21\u578b\u63d0\u793a<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">ModelHint<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4f7f\u7528\u9ed8\u8ba4\u6a21\u578b<\/span><br \/>\n    <span class=\"token class-name\">Default<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6307\u5b9a\u6a21\u578b<\/span><br \/>\n    <span class=\"token class-name\">Specific<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5feb\u901f\u6a21\u578b&#xff08;\u4f4e\u5ef6\u8fdf&#xff09;<\/span><br \/>\n    <span class=\"token class-name\">Fast<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5f3a\u529b\u6a21\u578b&#xff08;\u9ad8\u8d28\u91cf&#xff09;<\/span><br \/>\n    <span class=\"token class-name\">Powerful<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4ee3\u7801\u4e13\u7528<\/span><br \/>\n    <span class=\"token class-name\">Code<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u63a8\u7406\u4e13\u7528<\/span><br \/>\n    <span class=\"token class-name\">Reasoning<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u6a21\u578b\u7ea6\u675f<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ModelConstraints<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6700\u5927\u5ef6\u8fdf<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> max_latency<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Duration<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6700\u5927\u6210\u672c&#xff08;\u6bcf1000Token&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> max_cost_per_1k<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">f64<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6700\u4f4e\u8d28\u91cf\u8981\u6c42<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> min_quality<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">f64<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4e0a\u4e0b\u6587\u7a97\u53e3\u9700\u6c42<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> context_window_needed<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u662f\u5426\u9700\u8981\u51fd\u6570\u8c03\u7528\u80fd\u529b<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> needs_function_calling<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u662f\u5426\u9700\u8981\u89c6\u89c9\u80fd\u529b<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> needs_vision<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u8bf7\u6c42\u4f18\u5148\u7ea7<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token type-definition class-name\">RequestPriority<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4f4e\u4f18\u5148\u7ea7&#xff08;\u53ef\u6392\u961f&#xff09;<\/span><br \/>\n    <span class=\"token class-name\">Low<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u666e\u901a\u4f18\u5148\u7ea7<\/span><br \/>\n    <span class=\"token class-name\">Normal<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u9ad8\u4f18\u5148\u7ea7&#xff08;\u4f18\u5148\u8c03\u5ea6&#xff09;<\/span><br \/>\n    <span class=\"token class-name\">High<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u7d27\u6025&#xff08;\u6700\u9ad8\u4f18\u5148\u7ea7&#xff0c;\u53ef\u62a2\u5360&#xff09;<\/span><br \/>\n    <span class=\"token class-name\">Urgent<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u6a21\u578b\u8def\u7531\u5668\u6839\u636e Gateway \u63d0\u4f9b\u7684\u63d0\u793a\u548c\u7ea6\u675f&#xff0c;\u7efc\u5408\u8003\u8651\u4ee5\u4e0b\u56e0\u7d20\u9009\u62e9\u6700\u4f18\u6a21\u578b&#xff1a;<\/p>\n<table>\n<tr>\u51b3\u7b56\u56e0\u7d20\u6743\u91cd\u8bf4\u660e<\/tr>\n<tbody>\n<tr>\n<td>\u80fd\u529b\u5339\u914d<\/td>\n<td>0.30<\/td>\n<td>\u6a21\u578b\u662f\u5426\u5177\u5907\u6240\u9700\u80fd\u529b&#xff08;\u51fd\u6570\u8c03\u7528\u3001\u89c6\u89c9\u7b49&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>\u5ef6\u8fdf<\/td>\n<td>0.25<\/td>\n<td>\u6a21\u578b\u7684\u5e73\u5747\u54cd\u5e94\u5ef6\u8fdf<\/td>\n<\/tr>\n<tr>\n<td>\u6210\u672c<\/td>\n<td>0.20<\/td>\n<td>\u6bcf1000 Token \u7684\u4ef7\u683c<\/td>\n<\/tr>\n<tr>\n<td>\u8d28\u91cf<\/td>\n<td>0.15<\/td>\n<td>\u6a21\u578b\u5728\u76f8\u5173\u4efb\u52a1\u4e0a\u7684\u57fa\u51c6\u8bc4\u5206<\/td>\n<\/tr>\n<tr>\n<td>\u53ef\u7528\u6027<\/td>\n<td>0.10<\/td>\n<td>\u6a21\u578b\u5f53\u524d\u662f\u5426\u53ef\u7528&#xff0c;\u8d1f\u8f7d\u60c5\u51b5<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>6.3 \u4e0e\u81ea\u8fdb\u5316\u5f15\u64ce\u7684\u534f\u4f5c<\/h3>\n<h4>6.3.1 \u4ea4\u4e92\u67b6\u6784<\/h4>\n<p>\u81ea\u8fdb\u5316\u5f15\u64ce\u662f Hermes Agent \u7684\u5dee\u5f02\u5316\u80fd\u529b\u4e4b\u4e00\u3002\u5b83\u6301\u7eed\u5206\u6790 Gateway \u7684\u8fd0\u884c\u6570\u636e&#xff0c;\u4f18\u5316\u8def\u7531\u7b56\u7565\u3001\u5de5\u5177\u914d\u7f6e\u548c\u7cfb\u7edf\u53c2\u6570&#xff1a;<\/p>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502            Gateway \u4e0e\u81ea\u8fdb\u5316\u5f15\u64ce\u7684\u534f\u4f5c\u67b6\u6784                                \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510         \u2502<br \/>\n\u2502  \u2502             \u2502  1.\u8fd0\u884c\u6570\u636e\u4e0a\u62a5      \u2502                     \u2502         \u2502<br \/>\n\u2502  \u2502   Gateway   \u2502 \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550&gt; \u2502                     \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502  (\u6307\u6807\u3001\u65e5\u5fd7\u3001       \u2502   \u81ea\u8fdb\u5316\u5f15\u64ce          \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502   \u8ffd\u8e2a\u6570\u636e)         \u2502  (Self-Evolution)   \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502                    \u2502                     \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502  2.\u7b56\u7565\u4e0b\u53d1         \u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502 &lt;\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 \u2502  \u2502 \u6570\u636e\u5206\u6790\u5668     \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502  (\u4f18\u5316\u540e\u7684          \u2502  \u2502 \u00b7 \u6027\u80fd\u5206\u6790     \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502   \u8def\u7531\u89c4\u5219\u3001        \u2502  \u2502 \u00b7 \u8d28\u91cf\u8bc4\u4f30     \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502   \u53c2\u6570\u914d\u7f6e\u3001        \u2502  \u2502 \u00b7 \u5f02\u5e38\u68c0\u6d4b     \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502   \u6a21\u578b\u9009\u62e9\u7b56\u7565)     \u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502                    \u2502          \u2502          \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502  3.\u70ed\u52a0\u8f7d\u914d\u7f6e       \u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500v\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502 (\u65e0\u9700\u91cd\u542f)          \u2502  \u2502 \u7b56\u7565\u4f18\u5316\u5668     \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502                    \u2502  \u2502 \u00b7 \u8def\u7531\u4f18\u5316     \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502  4.AB\u6d4b\u8bd5\u53cd\u9988       \u2502  \u2502 \u00b7 \u53c2\u6570\u8c03\u4f18     \u2502  \u2502         \u2502<br \/>\n\u2502  \u2502             \u2502 \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550&gt; \u2502  \u2502 \u00b7 \u6a21\u578b\u9009\u62e9     \u2502  \u2502         \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                    \u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2502         \u2502<br \/>\n\u2502                                     \u2502          \u2502          \u2502         \u2502<br \/>\n\u2502                                     \u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500v\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u2502         \u2502<br \/>\n\u2502                                     \u2502  \u2502 \u7b56\u7565\u4e0b\u53d1\u5668     \u2502  \u2502         \u2502<br \/>\n\u2502                                     \u2502  \u2502 \u00b7 \u914d\u7f6e\u63a8\u9001     \u2502  \u2502         \u2502<br \/>\n\u2502                                     \u2502  \u2502 \u00b7 AB\u6d4b\u8bd5\u7ba1\u7406   \u2502  \u2502         \u2502<br \/>\n\u2502                                     \u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2502         \u2502<br \/>\n\u2502                                     \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518         \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<h4>6.3.2 \u6570\u636e\u4e0a\u62a5\u4e0e\u7b56\u7565\u63a5\u6536<\/h4>\n<p><span class=\"token comment\">\/\/\/ \u81ea\u8fdb\u5316\u5f15\u64ce\u4ea4\u4e92\u5ba2\u6237\u7aef<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">EvolutionClient<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ gRPC \u5ba2\u6237\u7aef<\/span><br \/>\n    client<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">EvolutionServiceClient<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6570\u636e\u4e0a\u62a5\u7f13\u51b2\u533a<\/span><br \/>\n    report_buffer<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">EvolutionDataPoint<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5f53\u524d\u751f\u6548\u7684\u7b56\u7565\u7248\u672c<\/span><br \/>\n    active_strategy_version<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">u64<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u8fd0\u884c\u6570\u636e\u70b9<\/span><br \/>\n<span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">EvolutionDataPoint<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> timestamp<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">DateTime<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> session_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> intent<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> model_used<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> tools_used<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> latency_ms<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> tokens_consumed<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> user_satisfaction<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">f64<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> success<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">bool<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> error<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u81ea\u8fdb\u5316\u7b56\u7565<\/span><br \/>\n<span class=\"token attribute attr-name\">#[derive(Clone, Debug, Serialize, Deserialize)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">EvolutionStrategy<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> strategy_version<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">u64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> routing_rules<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">OptimizedRoutingRule<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> model_preferences<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> tool_priorities<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">f64<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> parameter_overrides<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token namespace\">serde_json<span class=\"token punctuation\">::<\/span><\/span><span class=\"token class-name\">Value<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> ab_test_config<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">ABTestConfig<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">EvolutionClient<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6279\u91cf\u4e0a\u62a5\u8fd0\u884c\u6570\u636e<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">report_batch<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">EvolutionError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> buffer <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>report_buffer<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> buffer<span class=\"token punctuation\">.<\/span><span class=\"token function\">is_empty<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> data_points <span class=\"token operator\">&#061;<\/span> <span class=\"token namespace\">std<span class=\"token punctuation\">::<\/span>mem<span class=\"token punctuation\">::<\/span><\/span><span class=\"token function\">take<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">mut<\/span> <span class=\"token operator\">*<\/span>buffer<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token function\">drop<\/span><span class=\"token punctuation\">(<\/span>buffer<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>client<span class=\"token punctuation\">.<\/span><span class=\"token function\">report_data<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ReportRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            data_points<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u63a5\u6536\u7b56\u7565\u66f4\u65b0<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">receive_strategy_update<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">EvolutionStrategy<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">EvolutionError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> current_version <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">*<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>active_strategy_version<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> response <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>client<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">get_latest_strategy<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">GetStrategyRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                current_version<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> response<span class=\"token punctuation\">.<\/span>strategy<span class=\"token punctuation\">.<\/span><span class=\"token function\">is_none<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">None<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> strategy <span class=\"token operator\">&#061;<\/span> response<span class=\"token punctuation\">.<\/span>strategy<span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u66f4\u65b0\u7248\u672c\u53f7<\/span><br \/>\n        <span class=\"token operator\">*<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>active_strategy_version<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span> <span class=\"token operator\">&#061;<\/span> strategy<span class=\"token punctuation\">.<\/span>strategy_version<span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>strategy<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u5e94\u7528\u7b56\u7565\u5230 Gateway<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">apply_strategy<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        strategy<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">EvolutionStrategy<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        gateway<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Gateway<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">EvolutionError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ 1. \u66f4\u65b0\u8def\u7531\u89c4\u5219<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> rule <span class=\"token keyword\">in<\/span> <span class=\"token operator\">&amp;<\/span>strategy<span class=\"token punctuation\">.<\/span>routing_rules <span class=\"token punctuation\">{<\/span><br \/>\n            gateway<span class=\"token punctuation\">.<\/span>routing_engine<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">update_rule<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 2. \u66f4\u65b0\u6a21\u578b\u504f\u597d<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span>intent<span class=\"token punctuation\">,<\/span> model<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">in<\/span> <span class=\"token operator\">&amp;<\/span>strategy<span class=\"token punctuation\">.<\/span>model_preferences <span class=\"token punctuation\">{<\/span><br \/>\n            gateway<span class=\"token punctuation\">.<\/span>routing_engine<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">set_model_preference<\/span><span class=\"token punctuation\">(<\/span>intent<span class=\"token punctuation\">,<\/span> model<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 3. \u66f4\u65b0\u5de5\u5177\u4f18\u5148\u7ea7<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span>tool<span class=\"token punctuation\">,<\/span> priority<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">in<\/span> <span class=\"token operator\">&amp;<\/span>strategy<span class=\"token punctuation\">.<\/span>tool_priorities <span class=\"token punctuation\">{<\/span><br \/>\n            gateway<span class=\"token punctuation\">.<\/span>tool_registry<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">set_tool_priority<\/span><span class=\"token punctuation\">(<\/span>tool<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">*<\/span>priority<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 4. \u5e94\u7528\u53c2\u6570\u8986\u76d6<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span>key<span class=\"token punctuation\">,<\/span> value<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">in<\/span> <span class=\"token operator\">&amp;<\/span>strategy<span class=\"token punctuation\">.<\/span>parameter_overrides <span class=\"token punctuation\">{<\/span><br \/>\n            gateway<span class=\"token punctuation\">.<\/span>config<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">override_parameter<\/span><span class=\"token punctuation\">(<\/span>key<span class=\"token punctuation\">,<\/span> value<span class=\"token punctuation\">.<\/span><span class=\"token function\">clone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 5. \u914d\u7f6eAB\u6d4b\u8bd5&#xff08;\u5982\u679c\u6709&#xff09;<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>ab_config<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&amp;<\/span>strategy<span class=\"token punctuation\">.<\/span>ab_test_config <span class=\"token punctuation\">{<\/span><br \/>\n            gateway<span class=\"token punctuation\">.<\/span>ab_test_manager<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">start_experiment<\/span><span class=\"token punctuation\">(<\/span>ab_config<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token namespace\">tracing<span class=\"token punctuation\">::<\/span><\/span><span class=\"token macro property\">info!<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            version <span class=\"token operator\">&#061;<\/span> strategy<span class=\"token punctuation\">.<\/span>strategy_version<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string\">&#034;Evolution strategy applied successfully&#034;<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>6.3.3 \u7b56\u7565\u4f18\u5316\u793a\u4f8b<\/h4>\n<p>\u81ea\u8fdb\u5316\u5f15\u64ce\u901a\u8fc7\u5206\u6790\u5386\u53f2\u6570\u636e&#xff0c;\u6301\u7eed\u4f18\u5316 Gateway \u7684\u8def\u7531\u7b56\u7565\u3002\u4ee5\u4e0b\u662f\u4e00\u4e2a\u4f18\u5316\u793a\u4f8b&#xff1a;<\/p>\n<p><span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token string-property property\">&#034;strategy_version&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">42<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;routing_rules&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span><br \/>\n    <span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token string-property property\">&#034;intent&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;data_analysis&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;optimized_model&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;claude-3.5-sonnet&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;reason&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;\u5728\u6570\u636e\u5206\u6790\u4efb\u52a1\u4e0a&#xff0c;Claude 3.5 Sonnet \u7684\u51c6\u786e\u7387\u6bd4 GPT-4o \u9ad8 8%&#xff0c;\u4e14\u6210\u672c\u66f4\u4f4e&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;confidence&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">0.92<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;sample_size&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">1500<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token string-property property\">&#034;intent&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;code_execution&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;optimized_model&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;gpt-4o&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;reason&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;\u4ee3\u7801\u6267\u884c\u4efb\u52a1\u7684\u51fd\u6570\u8c03\u7528\u51c6\u786e\u7387 GPT-4o \u9886\u5148 12%&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;confidence&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">0.95<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;sample_size&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">3200<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token string-property property\">&#034;intent&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;casual_chat&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;optimized_model&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;gpt-4o-mini&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;reason&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;\u95f2\u804a\u4efb\u52a1\u5bf9\u6a21\u578b\u80fd\u529b\u8981\u6c42\u4f4e&#xff0c;\u4f7f\u7528 mini \u6a21\u578b\u53ef\u964d\u4f4e 80% \u6210\u672c&#xff0c;\u8d28\u91cf\u5dee\u5f02 &lt;3%&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;confidence&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">0.88<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;sample_size&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">5800<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n  <span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;tool_priorities&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token string-property property\">&#034;web_search&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">0.95<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token string-property property\">&#034;code_execution&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">0.90<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token string-property property\">&#034;knowledge_query&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">0.85<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;parameter_overrides&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token string-property property\">&#034;session.context_window.max_tokens&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">40960<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token string-property property\">&#034;routing.parallel_task_limit&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">6<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token string-property property\">&#034;tools.sandbox.timeout&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;45s&#034;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;ab_test_config&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token string-property property\">&#034;experiment_name&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;intent_detection_v3&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token string-property property\">&#034;control_group&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;rule_based_v2&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token string-property property\">&#034;treatment_group&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;ml_model_v3&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token string-property property\">&#034;traffic_split&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">0.2<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token string-property property\">&#034;metrics&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;accuracy&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;latency&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;user_satisfaction&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token string-property property\">&#034;duration&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;7d&#034;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<hr \/>\n<h2>\u7b2c\u4e03\u7ae0 Gateway \u6027\u80fd\u4e0e\u6269\u5c55\u6027<\/h2>\n<h3>7.1 \u5e76\u53d1\u5904\u7406\u80fd\u529b<\/h3>\n<h4>7.1.1 \u5e76\u53d1\u67b6\u6784<\/h4>\n<p>Gateway \u57fa\u4e8e Rust &#043; Tokio \u5f02\u6b65\u8fd0\u884c\u65f6\u6784\u5efa&#xff0c;\u91c7\u7528\u4e8b\u4ef6\u9a71\u52a8\u67b6\u6784\u5b9e\u73b0\u9ad8\u5e76\u53d1\u5904\u7406\u3002\u4ee5\u4e0b\u662f Gateway \u5728\u4e0d\u540c\u8d1f\u8f7d\u7ea7\u522b\u4e0b\u7684\u5e76\u53d1\u5904\u7406\u80fd\u529b\u6307\u6807&#xff1a;<\/p>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502                    Gateway \u5e76\u53d1\u5904\u7406\u80fd\u529b                                 \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u8d1f\u8f7d\u7ea7\u522b       QPS        \u5e73\u5747\u5ef6\u8fdf    P99\u5ef6\u8fdf    CPU    \u5185\u5b58         \u2502<br \/>\n\u2502  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500    \u2500\u2500\u2500\u2500\u2500\u2500\u2500    \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500  \u2500\u2500\u2500\u2500\u2500  \u2500\u2500\u2500\u2500\u2500\u2500        \u2502<br \/>\n\u2502  \u8f7b\u8d1f\u8f7d        100        45ms       120ms     15%    512MB         \u2502<br \/>\n\u2502  \u4e2d\u8d1f\u8f7d        500        65ms       200ms     45%    1.2GB         \u2502<br \/>\n\u2502  \u9ad8\u8d1f\u8f7d        1000       95ms       350ms     72%    2.1GB         \u2502<br \/>\n\u2502  \u5cf0\u503c\u8d1f\u8f7d      2000       180ms      650ms     91%    3.5GB         \u2502<br \/>\n\u2502  \u6781\u9650\u8d1f\u8f7d      3500       420ms      1200ms    98%    4.8GB         \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u6d4b\u8bd5\u73af\u5883:                                                            \u2502<br \/>\n\u2502  \u00b7 16\u6838 CPU (AMD EPYC 7763)                                         \u2502<br \/>\n\u2502  \u00b7 64GB \u5185\u5b58                                                         \u2502<br \/>\n\u2502  \u00b7 10Gbps \u7f51\u7edc                                                       \u2502<br \/>\n\u2502  \u00b7 Redis Cluster (6\u8282\u70b9)                                             \u2502<br \/>\n\u2502  \u00b7 Kafka (3\u8282\u70b9)                                                     \u2502<br \/>\n\u2502  \u00b7 \u6a21\u578b\u63a8\u7406\u5ef6\u8fdf\u4e0d\u8ba1\u5165&#xff08;\u4f7f\u7528\u6a21\u62df\u54cd\u5e94&#xff09;                                    \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<h4>7.1.2 \u5e76\u53d1\u4f18\u5316\u7b56\u7565<\/h4>\n<p><span class=\"token comment\">\/\/\/ Gateway \u5e76\u53d1\u4f18\u5316\u914d\u7f6e<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ConcurrencyConfig<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ Tokio worker \u7ebf\u7a0b\u6570<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> worker_threads<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u963b\u585e\u7ebf\u7a0b\u6c60\u5927\u5c0f<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> blocking_threads<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6bcf\u8fde\u63a5\u5e76\u53d1\u8bf7\u6c42\u6570<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> max_concurrent_requests_per_connection<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5168\u5c40\u5e76\u53d1\u8bf7\u6c42\u4e0a\u9650<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> max_concurrent_requests<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u8bf7\u6c42\u961f\u5217\u5bb9\u91cf<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> request_queue_capacity<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u8fde\u63a5\u6c60\u914d\u7f6e<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> connection_pools<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ConnectionPoolConfig<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/\/ \u8fde\u63a5\u6c60\u914d\u7f6e<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ConnectionPoolConfig<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ Redis \u8fde\u63a5\u6c60<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> redis<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">PoolConfig<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        min_connections<span class=\"token punctuation\">:<\/span> <span class=\"token number\">10<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        max_connections<span class=\"token punctuation\">:<\/span> <span class=\"token number\">100<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        connection_timeout<span class=\"token punctuation\">:<\/span> 3s<span class=\"token punctuation\">,<\/span><br \/>\n        idle_timeout<span class=\"token punctuation\">:<\/span> 300s<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ gRPC \u8fde\u63a5\u6c60<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> grpc<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">PoolConfig<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        min_connections<span class=\"token punctuation\">:<\/span> <span class=\"token number\">5<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        max_connections<span class=\"token punctuation\">:<\/span> <span class=\"token number\">50<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        connection_timeout<span class=\"token punctuation\">:<\/span> 5s<span class=\"token punctuation\">,<\/span><br \/>\n        idle_timeout<span class=\"token punctuation\">:<\/span> 600s<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ HTTP \u8fde\u63a5\u6c60<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> http<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">PoolConfig<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        min_connections<span class=\"token punctuation\">:<\/span> <span class=\"token number\">10<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        max_connections<span class=\"token punctuation\">:<\/span> <span class=\"token number\">200<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        connection_timeout<span class=\"token punctuation\">:<\/span> 3s<span class=\"token punctuation\">,<\/span><br \/>\n        idle_timeout<span class=\"token punctuation\">:<\/span> 90s<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Gateway \u7684\u5e76\u53d1\u4f18\u5316\u7b56\u7565\u5305\u62ec\u4ee5\u4e0b\u51e0\u4e2a\u5c42\u9762&#xff1a;<\/p>\n<p>1. \u5f02\u6b65IO\u591a\u8def\u590d\u7528&#xff1a;\u6240\u6709IO\u64cd\u4f5c&#xff08;\u7f51\u7edc\u3001\u78c1\u76d8\u3001\u6570\u636e\u5e93&#xff09;\u5747\u4f7f\u7528 async\/await \u5f02\u6b65\u6a21\u578b&#xff0c;\u5355\u7ebf\u7a0b\u53ef\u5904\u7406\u6570\u5343\u4e2a\u5e76\u53d1\u8fde\u63a5&#xff0c;\u7ebf\u7a0b\u5207\u6362\u5f00\u9500\u8d8b\u8fd1\u4e8e\u96f6\u3002<\/p>\n<p>2. \u96f6\u62f7\u8d1d\u6d88\u606f\u4f20\u9012&#xff1a;\u5728\u6d88\u606f\u5f52\u4e00\u5316\u7ba1\u7ebf\u548c\u4efb\u52a1\u7f16\u6392\u5668\u4e4b\u95f4&#xff0c;\u4f7f\u7528 Bytes \u7c7b\u578b\u4f20\u9012\u6d88\u606f\u4f53&#xff0c;\u907f\u514d\u4e0d\u5fc5\u8981\u7684\u6570\u636e\u62f7\u8d1d\u3002<\/p>\n<p>3. \u5206\u7247\u9501\u8bbe\u8ba1&#xff1a;\u5bf9\u4e8e\u9ad8\u9891\u8bbf\u95ee\u7684\u5171\u4eab\u6570\u636e\u7ed3\u6784&#xff08;\u5982\u4f1a\u8bdd\u6ce8\u518c\u8868\u3001\u5de5\u5177\u6ce8\u518c\u8868&#xff09;&#xff0c;\u91c7\u7528\u5206\u7247\u9501&#xff08;Sharded Lock&#xff09;\u66ff\u4ee3\u5168\u5c40\u9501&#xff0c;\u5c06\u9501\u7ade\u4e89\u964d\u4f4e\u5230 1\/N\u3002<\/p>\n<p><span class=\"token comment\">\/\/\/ \u5206\u7247\u9501\u5b9e\u73b0<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">ShardedMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">K<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">V<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">const<\/span> <span class=\"token class-name\">N<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    shards<span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">K<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">V<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token class-name\">N<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">K<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Hash<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token class-name\">Eq<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token class-name\">Clone<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">V<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Clone<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">const<\/span> <span class=\"token class-name\">N<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token class-name\">ShardedMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">K<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">V<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">N<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">get_shard<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> key<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">K<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">K<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">V<\/span><span class=\"token operator\">&gt;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> <span class=\"token keyword\">mut<\/span> hasher <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">DefaultHasher<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">new<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        key<span class=\"token punctuation\">.<\/span><span class=\"token function\">hash<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">mut<\/span> hasher<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> hash <span class=\"token operator\">&#061;<\/span> hasher<span class=\"token punctuation\">.<\/span><span class=\"token function\">finish<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>shards<span class=\"token punctuation\">[<\/span>hash <span class=\"token operator\">%<\/span> <span class=\"token class-name\">N<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> key<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">K<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Option<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">V<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> shard <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get_shard<\/span><span class=\"token punctuation\">(<\/span>key<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        shard<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>key<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">cloned<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">insert<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> key<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">K<\/span><span class=\"token punctuation\">,<\/span> value<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">V<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> shard <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get_shard<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>key<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        shard<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">insert<\/span><span class=\"token punctuation\">(<\/span>key<span class=\"token punctuation\">,<\/span> value<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u4f7f\u7528\u793a\u4f8b&#xff1a;32\u7247\u5206\u7247\u9501<\/span><br \/>\n<span class=\"token keyword\">type<\/span> <span class=\"token type-definition class-name\">SessionShardedMap<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">ShardedMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">SessionId<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">SessionContext<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">32<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>4. \u80cc\u538b\u63a7\u5236&#xff1a;\u5f53\u4e0b\u6e38\u670d\u52a1&#xff08;\u6a21\u578b\u8def\u7531\u5668\u3001\u5de5\u5177\u6267\u884c\u5668&#xff09;\u5904\u7406\u901f\u5ea6\u8ddf\u4e0d\u4e0a\u65f6&#xff0c;Gateway \u901a\u8fc7\u80cc\u538b\u673a\u5236\u51cf\u6162\u4e0a\u6e38\u8bf7\u6c42\u7684\u63a5\u53d7\u901f\u7387&#xff0c;\u907f\u514d\u5185\u5b58\u5806\u79ef&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/\/ \u80cc\u538b\u63a7\u5236\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">BackpressureController<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5f53\u524d\u5e76\u53d1\u6570<\/span><br \/>\n    current_concurrent<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">AtomicUsize<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u6700\u5927\u5e76\u53d1\u6570<\/span><br \/>\n    max_concurrent<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u9ad8\u6c34\u4f4d\u7ebf&#xff08;\u5f00\u59cb\u9650\u6d41&#xff09;<\/span><br \/>\n    high_watermark<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4f4e\u6c34\u4f4d\u7ebf&#xff08;\u505c\u6b62\u9650\u6d41&#xff09;<\/span><br \/>\n    low_watermark<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">usize<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u662f\u5426\u5904\u4e8e\u9650\u6d41\u72b6\u6001<\/span><br \/>\n    is_throttling<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">AtomicBool<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">BackpressureController<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">acquire<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">Result<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Permit<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BackpressureError<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> current <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>current_concurrent<span class=\"token punctuation\">.<\/span><span class=\"token function\">load<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Ordering<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Relaxed<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> current <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>max_concurrent <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Err<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BackpressureError<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">MaxConcurrencyReached<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> current <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>high_watermark <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>is_throttling<span class=\"token punctuation\">.<\/span><span class=\"token function\">store<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Ordering<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Relaxed<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token comment\">\/\/ \u5f00\u59cb\u62d2\u7edd\u4f4e\u4f18\u5148\u7ea7\u8bf7\u6c42<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>current_concurrent<span class=\"token punctuation\">.<\/span><span class=\"token function\">fetch_add<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Ordering<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Relaxed<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Ok<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Permit<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            controller<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">release<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> current <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>current_concurrent<span class=\"token punctuation\">.<\/span><span class=\"token function\">fetch_sub<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Ordering<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Relaxed<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#8211;<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> current <span class=\"token operator\">&lt;&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>low_watermark <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>is_throttling<span class=\"token punctuation\">.<\/span><span class=\"token function\">store<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Ordering<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Relaxed<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>5. \u9884\u70ed\u4e0e\u7f13\u5b58&#xff1a;\u6c99\u7bb1\u5b9e\u4f8b\u9884\u70ed\u3001\u4f1a\u8bdd\u4e0a\u4e0b\u6587\u9884\u52a0\u8f7d\u3001\u5de5\u5177\u63cf\u8ff0\u7b26\u7f13\u5b58\u7b49\u9884\u70ed\u673a\u5236\u786e\u4fdd\u70ed\u8def\u5f84\u4e0a\u7684\u96f6\u51b7\u542f\u52a8\u5ef6\u8fdf\u3002<\/p>\n<h3>7.2 \u6c34\u5e73\u6269\u5c55\u65b9\u6848<\/h3>\n<h4>7.2.1 \u96c6\u7fa4\u67b6\u6784<\/h4>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502                    Gateway \u96c6\u7fa4\u67b6\u6784                                     \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502                      \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                                 \u2502<br \/>\n\u2502                      \u2502   \u8d1f\u8f7d\u5747\u8861\u5668   \u2502                                 \u2502<br \/>\n\u2502                      \u2502  (LB \/ VIP)  \u2502                                 \u2502<br \/>\n\u2502                      \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                                 \u2502<br \/>\n\u2502                              \u2502                                        \u2502<br \/>\n\u2502              \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                       \u2502<br \/>\n\u2502              \u2502               \u2502               \u2502                       \u2502<br \/>\n\u2502              v               v               v                       \u2502<br \/>\n\u2502        \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                 \u2502<br \/>\n\u2502        \u2502 Gateway  \u2502    \u2502 Gateway  \u2502    \u2502 Gateway  \u2502                 \u2502<br \/>\n\u2502        \u2502 Node 1   \u2502    \u2502 Node 2   \u2502    \u2502 Node 3   \u2502                 \u2502<br \/>\n\u2502        \u2514\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2518                 \u2502<br \/>\n\u2502             \u2502               \u2502               \u2502                        \u2502<br \/>\n\u2502             \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                       \u2502<br \/>\n\u2502                              \u2502                                        \u2502<br \/>\n\u2502              \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                       \u2502<br \/>\n\u2502              \u2502               \u2502               \u2502                       \u2502<br \/>\n\u2502              v               v               v                       \u2502<br \/>\n\u2502        \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                 \u2502<br \/>\n\u2502        \u2502 Redis    \u2502    \u2502 Kafka    \u2502    \u2502  etcd    \u2502                 \u2502<br \/>\n\u2502        \u2502 Cluster  \u2502    \u2502 Cluster  \u2502    \u2502 Cluster  \u2502                 \u2502<br \/>\n\u2502        \u2502 (\u4f1a\u8bdd)    \u2502    \u2502 (\u6d88\u606f)    \u2502    \u2502 (\u914d\u7f6e)    \u2502                 \u2502<br \/>\n\u2502        \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                 \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u6269\u5c55\u65b9\u5f0f:                                                            \u2502<br \/>\n\u2502  \u00b7 \u65e0\u72b6\u6001 Gateway \u8282\u70b9\u53ef\u968f\u65f6\u589e\u51cf                                       \u2502<br \/>\n\u2502  \u00b7 \u4f1a\u8bdd\u6570\u636e\u5b58\u50a8\u5728 Redis Cluster&#xff0c;\u4e0d\u4f9d\u8d56\u5355\u8282\u70b9                           \u2502<br \/>\n\u2502  \u00b7 \u914d\u7f6e\u901a\u8fc7 etcd \u5b9e\u65f6\u540c\u6b65\u5230\u6240\u6709\u8282\u70b9                                     \u2502<br \/>\n\u2502  \u00b7 \u8282\u70b9\u95f4\u901a\u8fc7 Kafka \u4f20\u9012\u5f02\u6b65\u6d88\u606f                                       \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<h4>7.2.2 \u65e0\u72b6\u6001\u8bbe\u8ba1<\/h4>\n<p>Gateway \u8282\u70b9\u8bbe\u8ba1\u4e3a\u65e0\u72b6\u6001&#xff0c;\u6240\u6709\u72b6\u6001\u5b58\u50a8\u5728\u5916\u90e8\u7cfb\u7edf\u4e2d&#xff1a;<\/p>\n<table>\n<tr>\u72b6\u6001\u7c7b\u578b\u5b58\u50a8\u4f4d\u7f6e\u8bbf\u95ee\u65b9\u5f0f\u4e00\u81f4\u6027\u8981\u6c42<\/tr>\n<tbody>\n<tr>\n<td>\u4f1a\u8bdd\u4e0a\u4e0b\u6587<\/td>\n<td>Redis Cluster<\/td>\n<td>\u8bfb\u5199<\/td>\n<td>\u5f3a\u4e00\u81f4\u6027<\/td>\n<\/tr>\n<tr>\n<td>\u5de5\u5177\u6ce8\u518c\u8868<\/td>\n<td>etcd &#043; \u672c\u5730\u7f13\u5b58<\/td>\n<td>\u8bfb\u5199&#xff08;\u6ce8\u518c&#xff09;\/\u53ea\u8bfb&#xff08;\u67e5\u8be2&#xff09;<\/td>\n<td>\u6700\u7ec8\u4e00\u81f4\u6027<\/td>\n<\/tr>\n<tr>\n<td>\u8def\u7531\u914d\u7f6e<\/td>\n<td>etcd<\/td>\n<td>\u53ea\u8bfb<\/td>\n<td>\u6700\u7ec8\u4e00\u81f4\u6027<\/td>\n<\/tr>\n<tr>\n<td>\u5ba1\u8ba1\u65e5\u5fd7<\/td>\n<td>Kafka \u2192 ES<\/td>\n<td>\u53ea\u5199<\/td>\n<td>\u81f3\u5c11\u4e00\u6b21<\/td>\n<\/tr>\n<tr>\n<td>\u6307\u6807\u6570\u636e<\/td>\n<td>Prometheus<\/td>\n<td>\u53ea\u5199<\/td>\n<td>\u5c3d\u529b\u800c\u4e3a<\/td>\n<\/tr>\n<tr>\n<td>\u4e34\u65f6\u7f13\u5b58<\/td>\n<td>\u672c\u5730\u5185\u5b58<\/td>\n<td>\u8bfb\u5199<\/td>\n<td>\u65e0&#xff08;\u53ef\u4e22\u5931&#xff09;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>7.2.3 \u81ea\u52a8\u4f38\u7f29<\/h4>\n<p><span class=\"token comment\"># Kubernetes HPA \u914d\u7f6e<\/span><br \/>\n<span class=\"token key atrule\">apiVersion<\/span><span class=\"token punctuation\">:<\/span> autoscaling\/v2<br \/>\n<span class=\"token key atrule\">kind<\/span><span class=\"token punctuation\">:<\/span> HorizontalPodAutoscaler<br \/>\n<span class=\"token key atrule\">metadata<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> gateway<span class=\"token punctuation\">&#8211;<\/span>hpa<br \/>\n  <span class=\"token key atrule\">namespace<\/span><span class=\"token punctuation\">:<\/span> hermes<br \/>\n<span class=\"token key atrule\">spec<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token key atrule\">scaleTargetRef<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">apiVersion<\/span><span class=\"token punctuation\">:<\/span> apps\/v1<br \/>\n    <span class=\"token key atrule\">kind<\/span><span class=\"token punctuation\">:<\/span> Deployment<br \/>\n    <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> gateway<br \/>\n  <span class=\"token key atrule\">minReplicas<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">3<\/span><br \/>\n  <span class=\"token key atrule\">maxReplicas<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">20<\/span><br \/>\n  <span class=\"token key atrule\">metrics<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> Resource<br \/>\n      <span class=\"token key atrule\">resource<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> cpu<br \/>\n        <span class=\"token key atrule\">target<\/span><span class=\"token punctuation\">:<\/span><br \/>\n          <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> Utilization<br \/>\n          <span class=\"token key atrule\">averageUtilization<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">70<\/span><br \/>\n    <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> Resource<br \/>\n      <span class=\"token key atrule\">resource<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> memory<br \/>\n        <span class=\"token key atrule\">target<\/span><span class=\"token punctuation\">:<\/span><br \/>\n          <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> Utilization<br \/>\n          <span class=\"token key atrule\">averageUtilization<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">75<\/span><br \/>\n    <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> Pods<br \/>\n      <span class=\"token key atrule\">pods<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token key atrule\">metric<\/span><span class=\"token punctuation\">:<\/span><br \/>\n          <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> gateway_active_sessions<br \/>\n        <span class=\"token key atrule\">target<\/span><span class=\"token punctuation\">:<\/span><br \/>\n          <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> AverageValue<br \/>\n          <span class=\"token key atrule\">averageValue<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;500&#034;<\/span><br \/>\n    <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> Pods<br \/>\n      <span class=\"token key atrule\">pods<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token key atrule\">metric<\/span><span class=\"token punctuation\">:<\/span><br \/>\n          <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> gateway_request_latency_p99<br \/>\n        <span class=\"token key atrule\">target<\/span><span class=\"token punctuation\">:<\/span><br \/>\n          <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> AverageValue<br \/>\n          <span class=\"token key atrule\">averageValue<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;500&#034;<\/span><br \/>\n  <span class=\"token key atrule\">behavior<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">scaleUp<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">stabilizationWindowSeconds<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">30<\/span><br \/>\n      <span class=\"token key atrule\">policies<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> Percent<br \/>\n          <span class=\"token key atrule\">value<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">50<\/span><br \/>\n          <span class=\"token key atrule\">periodSeconds<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">60<\/span><br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> Pods<br \/>\n          <span class=\"token key atrule\">value<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">4<\/span><br \/>\n          <span class=\"token key atrule\">periodSeconds<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">60<\/span><br \/>\n      <span class=\"token key atrule\">selectPolicy<\/span><span class=\"token punctuation\">:<\/span> Max<br \/>\n    <span class=\"token key atrule\">scaleDown<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">stabilizationWindowSeconds<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">300<\/span><br \/>\n      <span class=\"token key atrule\">policies<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">type<\/span><span class=\"token punctuation\">:<\/span> Percent<br \/>\n          <span class=\"token key atrule\">value<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">25<\/span><br \/>\n          <span class=\"token key atrule\">periodSeconds<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">120<\/span><br \/>\n      <span class=\"token key atrule\">selectPolicy<\/span><span class=\"token punctuation\">:<\/span> Min<\/p>\n<p>\u81ea\u52a8\u4f38\u7f29\u7684\u89e6\u53d1\u6761\u4ef6&#xff1a;<\/p>\n<table>\n<tr>\u6307\u6807\u6269\u5bb9\u9608\u503c\u7f29\u5bb9\u9608\u503c\u8bc4\u4f30\u7a97\u53e3<\/tr>\n<tbody>\n<tr>\n<td>CPU \u4f7f\u7528\u7387<\/td>\n<td>&gt;70%<\/td>\n<td>&lt;40%<\/td>\n<td>60\u79d2<\/td>\n<\/tr>\n<tr>\n<td>\u5185\u5b58\u4f7f\u7528\u7387<\/td>\n<td>&gt;75%<\/td>\n<td>&lt;45%<\/td>\n<td>60\u79d2<\/td>\n<\/tr>\n<tr>\n<td>\u6d3b\u8dc3\u4f1a\u8bdd\u6570\/\u8282\u70b9<\/td>\n<td>&gt;500<\/td>\n<td>&lt;200<\/td>\n<td>30\u79d2<\/td>\n<\/tr>\n<tr>\n<td>P99 \u8bf7\u6c42\u5ef6\u8fdf<\/td>\n<td>&gt;500ms<\/td>\n<td>&lt;200ms<\/td>\n<td>30\u79d2<\/td>\n<\/tr>\n<tr>\n<td>\u8bf7\u6c42\u961f\u5217\u6df1\u5ea6<\/td>\n<td>&gt;50<\/td>\n<td>&lt;10<\/td>\n<td>15\u79d2<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>7.3 \u6545\u969c\u6062\u590d\u673a\u5236<\/h3>\n<h4>7.3.1 \u6545\u969c\u68c0\u6d4b<\/h4>\n<p><span class=\"token comment\">\/\/\/ \u6545\u969c\u68c0\u6d4b\u5668<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">FailureDetector<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u8282\u70b9\u5065\u5eb7\u72b6\u6001<\/span><br \/>\n    node_health<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Arc<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">RwLock<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">HashMap<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">NodeId<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">NodeHealth<\/span><span class=\"token operator\">&gt;&gt;<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5fc3\u8df3\u8d85\u65f6<\/span><br \/>\n    heartbeat_timeout<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u5fc3\u8df3\u95f4\u9694<\/span><br \/>\n    heartbeat_interval<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ Phi Accusal \u6545\u969c\u68c0\u6d4b\u5668\u53c2\u6570<\/span><br \/>\n    phi_threshold<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">f64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token attribute attr-name\">#[derive(Clone, Debug)]<\/span><br \/>\n<span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token type-definition class-name\">NodeHealth<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> node_id<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">NodeId<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> status<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">NodeStatus<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> last_heartbeat<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">DateTime<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Utc<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> phi_value<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">f64<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> heartbeat_history<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">VecDeque<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Duration<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">impl<\/span> <span class=\"token class-name\">FailureDetector<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/\/ \u4f7f\u7528 Phi Accusal \u7b97\u6cd5\u68c0\u6d4b\u8282\u70b9\u6545\u969c<\/span><br \/>\n    <span class=\"token keyword\">pub<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">check_node<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span> node_id<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">NodeId<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token class-name\">NodeStatus<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> health <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>node_health<span class=\"token punctuation\">.<\/span><span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">await<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">let<\/span> <span class=\"token class-name\">Some<\/span><span class=\"token punctuation\">(<\/span>h<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> health<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>node_id<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> time_since_last <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Utc<\/span><span class=\"token punctuation\">::<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">signed_duration_since<\/span><span class=\"token punctuation\">(<\/span>h<span class=\"token punctuation\">.<\/span>last_heartbeat<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">to_std<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">unwrap_or_default<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u8ba1\u7b97 Phi \u503c<\/span><br \/>\n            <span class=\"token keyword\">let<\/span> phi <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">calculate_phi<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>h<span class=\"token punctuation\">.<\/span>heartbeat_history<span class=\"token punctuation\">,<\/span> time_since_last<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token keyword\">if<\/span> phi <span class=\"token operator\">&gt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>phi_threshold <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">NodeStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Suspected<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token keyword\">if<\/span> time_since_last <span class=\"token operator\">&gt;<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">.<\/span>heartbeat_timeout <span class=\"token operator\">*<\/span> <span class=\"token number\">3<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">NodeStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Dead<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">NodeStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Alive<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token class-name\">NodeStatus<\/span><span class=\"token punctuation\">::<\/span><span class=\"token class-name\">Unknown<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/\/ \u8ba1\u7b97 Phi \u503c&#xff08;\u57fa\u4e8e\u5fc3\u8df3\u5386\u53f2\u7684\u7edf\u8ba1\u68c0\u6d4b&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">fn<\/span> <span class=\"token function-definition function\">calculate_phi<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token operator\">&amp;<\/span><span class=\"token keyword\">self<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        history<span class=\"token punctuation\">:<\/span> <span class=\"token operator\">&amp;<\/span><span class=\"token class-name\">VecDeque<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">Duration<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        current_delay<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">-&gt;<\/span> <span class=\"token keyword\">f64<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> history<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&lt;<\/span> <span class=\"token number\">10<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token number\">0.0<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ \u5386\u53f2\u6570\u636e\u4e0d\u8db3<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8ba1\u7b97\u5fc3\u8df3\u95f4\u9694\u7684\u5747\u503c\u548c\u6807\u51c6\u5dee<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> intervals<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Vec<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">f64<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&#061;<\/span> history<span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>d<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> d<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_millis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">f64<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> mean <span class=\"token operator\">&#061;<\/span> intervals<span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">sum<\/span><span class=\"token punctuation\">::<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">f64<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">\/<\/span> intervals<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">f64<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> variance <span class=\"token operator\">&#061;<\/span> intervals<span class=\"token punctuation\">.<\/span><span class=\"token function\">iter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|<\/span>x<span class=\"token closure-punctuation punctuation\">|<\/span><\/span> <span class=\"token punctuation\">(<\/span>x <span class=\"token operator\">&#8211;<\/span> mean<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">powi<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">2<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">sum<\/span><span class=\"token punctuation\">::<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token keyword\">f64<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">\/<\/span> intervals<span class=\"token punctuation\">.<\/span><span class=\"token function\">len<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">f64<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> std_dev <span class=\"token operator\">&#061;<\/span> variance<span class=\"token punctuation\">.<\/span><span class=\"token function\">sqrt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> std_dev <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0.0<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">if<\/span> current_delay<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_millis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">f64<\/span> <span class=\"token operator\">&gt;<\/span> mean <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">f64<\/span><span class=\"token punctuation\">::<\/span><span class=\"token constant\">INFINITY<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token number\">0.0<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ Phi &#061; -log10(P(x &gt; now &#8211; last_heartbeat))<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> delay <span class=\"token operator\">&#061;<\/span> current_delay<span class=\"token punctuation\">.<\/span><span class=\"token function\">as_millis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> <span class=\"token keyword\">f64<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> phi <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token number\">1.0<\/span> <span class=\"token operator\">*<\/span><br \/>\n            <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1.0<\/span> <span class=\"token operator\">\/<\/span> <span class=\"token punctuation\">(<\/span>std_dev <span class=\"token operator\">*<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token number\">2.0<\/span> <span class=\"token operator\">*<\/span> <span class=\"token namespace\">std<span class=\"token punctuation\">::<\/span><\/span><span class=\"token keyword\">f64<\/span><span class=\"token punctuation\">::<\/span><span class=\"token namespace\">consts<span class=\"token punctuation\">::<\/span><\/span><span class=\"token constant\">PI<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">sqrt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">*<\/span><br \/>\n             <span class=\"token punctuation\">(<\/span><span class=\"token operator\">&#8211;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>delay <span class=\"token operator\">&#8211;<\/span> mean<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">powi<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">2<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">\/<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token number\">2.0<\/span> <span class=\"token operator\">*<\/span> variance<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ln<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        phi<br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>7.3.2 \u6545\u969c\u6062\u590d\u6d41\u7a0b<\/h4>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502                    \u6545\u969c\u6062\u590d\u6d41\u7a0b                                         \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  1. \u6545\u969c\u68c0\u6d4b                                                          \u2502<br \/>\n\u2502     \u2514\u2500&gt; Phi Accusal \u68c0\u6d4b\u5668\u53d1\u73b0 Node 2 \u5fc3\u8df3\u8d85\u65f6                         \u2502<br \/>\n\u2502         Phi &gt; 8.0 (\u9608\u503c) \u2192 \u6807\u8bb0\u4e3a Suspected                           \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  2. \u9a8c\u8bc1\u4e0e\u786e\u8ba4                                                        \u2502<br \/>\n\u2502     \u2514\u2500&gt; \u5176\u4ed6\u8282\u70b9\u5bf9 Node 2 \u6267\u884c TCP \u63a2\u6d4b                                \u2502<br \/>\n\u2502         \u591a\u6570\u8282\u70b9\u786e\u8ba4 \u2192 \u6807\u8bb0\u4e3a Dead                                     \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  3. \u5f71\u54cd\u8bc4\u4f30                                                          \u2502<br \/>\n\u2502     \u2514\u2500&gt; \u67e5\u8be2 Node 2 \u4e0a\u7684\u6d3b\u8dc3\u4f1a\u8bdd\u5217\u8868                                   \u2502<br \/>\n\u2502         \u8bc4\u4f30\u5f71\u54cd\u8303\u56f4&#xff1a;N \u4e2a\u6d3b\u8dc3\u4f1a\u8bdd\u9700\u8981\u8fc1\u79fb                              \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  4. \u81ea\u52a8\u6062\u590d                                                          \u2502<br \/>\n\u2502     \u251c\u2500&gt; 4a. \u4f1a\u8bdd\u8fc1\u79fb&#xff1a;\u4ece Redis \u526f\u672c\u6062\u590d\u5230\u5907\u7528\u8282\u70b9                       \u2502<br \/>\n\u2502     \u251c\u2500&gt; 4b. \u8bf7\u6c42\u91cd\u8def\u7531&#xff1a;\u4e00\u81f4\u6027\u54c8\u5e0c\u73af\u66f4\u65b0&#xff0c;\u65b0\u8bf7\u6c42\u8def\u7531\u5230\u5176\u4ed6\u8282\u70b9            \u2502<br \/>\n\u2502     \u251c\u2500&gt; 4c. \u961f\u5217\u91cd\u5206\u914d&#xff1a;Node 2 \u7684 Kafka \u5206\u533a\u6d88\u8d39\u8005\u91cd\u5e73\u8861               \u2502<br \/>\n\u2502     \u2514\u2500&gt; 4d. \u544a\u8b66\u901a\u77e5&#xff1a;\u53d1\u9001\u6545\u969c\u901a\u77e5\u5230\u8fd0\u7ef4\u901a\u9053                             \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  5. \u6062\u590d\u9a8c\u8bc1                                                          \u2502<br \/>\n\u2502     \u2514\u2500&gt; \u9a8c\u8bc1\u6240\u6709\u8fc1\u79fb\u4f1a\u8bdd\u7684\u6570\u636e\u5b8c\u6574\u6027                                    \u2502<br \/>\n\u2502         \u9a8c\u8bc1\u65b0\u8282\u70b9\u7684\u8bf7\u6c42\u5904\u7406\u6b63\u5e38                                        \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  6. \u8282\u70b9\u6062\u590d&#xff08;\u5982\u679c Node 2 \u6062\u590d&#xff09;                                       \u2502<br \/>\n\u2502     \u2514\u2500&gt; \u91cd\u65b0\u52a0\u5165\u96c6\u7fa4 \u2192 \u6570\u636e\u540c\u6b65 \u2192 \u9010\u6b65\u627f\u63a5\u6d41\u91cf                          \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<h4>7.3.3 \u5173\u952e\u6307\u6807\u7684\u6062\u590d\u65f6\u95f4\u76ee\u6807<\/h4>\n<table>\n<tr>\u6545\u969c\u7c7b\u578b\u68c0\u6d4b\u65f6\u95f4\u6062\u590d\u65f6\u95f4\u6570\u636e\u5f71\u54cd\u6062\u590d\u7b56\u7565<\/tr>\n<tbody>\n<tr>\n<td>Gateway \u8282\u70b9\u5d29\u6e83<\/td>\n<td>&lt;5s<\/td>\n<td>&lt;10s<\/td>\n<td>\u65e0<\/td>\n<td>\u8bf7\u6c42\u81ea\u52a8\u91cd\u8def\u7531<\/td>\n<\/tr>\n<tr>\n<td>Redis \u4e3b\u8282\u70b9\u6545\u969c<\/td>\n<td>&lt;3s<\/td>\n<td>&lt;30s<\/td>\n<td>\u65e0&#xff08;\u526f\u672c\u63a5\u7ba1&#xff09;<\/td>\n<td>Sentinel \u81ea\u52a8\u6545\u969c\u8f6c\u79fb<\/td>\n<\/tr>\n<tr>\n<td>Kafka Broker \u6545\u969c<\/td>\n<td>&lt;10s<\/td>\n<td>&lt;60s<\/td>\n<td>\u65e0&#xff08;\u591a\u526f\u672c&#xff09;<\/td>\n<td>\u5206\u533a\u91cd\u5e73\u8861<\/td>\n<\/tr>\n<tr>\n<td>\u6a21\u578b\u670d\u52a1\u4e0d\u53ef\u7528<\/td>\n<td>&lt;1s<\/td>\n<td>&lt;5s<\/td>\n<td>\u964d\u7ea7\u670d\u52a1<\/td>\n<td>\u81ea\u52a8\u5207\u6362\u5907\u7528\u6a21\u578b<\/td>\n<\/tr>\n<tr>\n<td>\u7f51\u7edc\u5206\u533a<\/td>\n<td>&lt;15s<\/td>\n<td>&lt;120s<\/td>\n<td>\u53ef\u80fd\u90e8\u5206\u8d85\u65f6<\/td>\n<td>\u62dc\u5360\u5ead\u5bb9\u9519\u5904\u7406<\/td>\n<\/tr>\n<tr>\n<td>\u6574\u673a\u623f\u65ad\u7535<\/td>\n<td>N\/A<\/td>\n<td>&lt;600s<\/td>\n<td>\u65e0&#xff08;\u8de8\u53ef\u7528\u533a&#xff09;<\/td>\n<td>\u8de8AZ\u81ea\u52a8\u5207\u6362<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<h2>\u7b2c\u516b\u7ae0 \u4e0e\u5176\u4ed6 Agent \u6846\u67b6\u7684 Gateway \u5bf9\u6bd4<\/h2>\n<h3>8.1 \u67b6\u6784\u54f2\u5b66\u5bf9\u6bd4<\/h3>\n<p>Hermes Agent \u7684 Gateway \u4e0e\u4e1a\u754c\u4e3b\u6d41 Agent \u6846\u67b6\u7684\u63a7\u5236\u5c42\u5728\u8bbe\u8ba1\u54f2\u5b66\u4e0a\u6709\u672c\u8d28\u5dee\u5f02\u3002\u4ee5\u4e0b\u4ece\u4e94\u4e2a\u7ef4\u5ea6\u8fdb\u884c\u5bf9\u6bd4\u5206\u6790&#xff1a;<\/p>\n<h4>8.1.1 LangChain Router<\/h4>\n<p>LangChain \u7684 Router \u6a21\u5757\u91c7\u7528\u94fe\u5f0f\u7ec4\u5408\u7684\u8bbe\u8ba1\u54f2\u5b66&#xff0c;\u5c06\u8def\u7531\u903b\u8f91\u8868\u8fbe\u4e3a\u4e00\u7cfb\u5217\u53ef\u7ec4\u5408\u7684 Chain\u3002\u5176\u6838\u5fc3\u601d\u60f3\u662f\u901a\u8fc7 LCEL&#xff08;LangChain Expression Language&#xff09;\u5c06\u610f\u56fe\u8bc6\u522b\u3001\u8bb0\u5fc6\u68c0\u7d22\u3001\u6a21\u578b\u8c03\u7528\u7b49\u73af\u8282\u4e32\u8054\u4e3a\u58f0\u660e\u5f0f\u7684\u5904\u7406\u94fe\u3002<\/p>\n<p>\u4f18\u52bf&#xff1a;\u7ec4\u5408\u7075\u6d3b&#xff0c;\u5f00\u53d1\u8005\u53ef\u4ee5\u5feb\u901f\u62fc\u88c5\u51fa\u4e0d\u540c\u7684\u5904\u7406\u6d41\u7a0b&#xff1b;\u793e\u533a\u751f\u6001\u4e30\u5bcc&#xff0c;\u6709\u5927\u91cf\u9884\u7f6e\u7684 Chain \u548c Tool \u53ef\u7528\u3002<\/p>\n<p>\u52a3\u52bf&#xff1a;\u7f3a\u4e4f\u7edf\u4e00\u7684\u4f1a\u8bdd\u7ba1\u7406&#xff0c;\u72b6\u6001\u5206\u6563\u5728\u5404 Chain \u4e2d&#xff1b;\u6e20\u9053\u9002\u914d\u9700\u8981\u81ea\u884c\u5b9e\u73b0&#xff1b;\u7f3a\u4e4f\u751f\u4ea7\u7ea7\u7684\u9ad8\u53ef\u7528\u548c\u6c34\u5e73\u6269\u5c55\u80fd\u529b&#xff1b;\u6027\u80fd\u53d7 Python GIL \u9650\u5236\u3002<\/p>\n<h4>8.1.2 AutoGen Orchestrator<\/h4>\n<p>AutoGen \u7684 Orchestrator \u91c7\u7528\u591a Agent \u534f\u4f5c\u7684\u8bbe\u8ba1\u54f2\u5b66&#xff0c;\u6838\u5fc3\u662f GroupChat \u673a\u5236\u2014\u2014\u591a\u4e2a Agent \u5728\u4e00\u4e2a\u7ec4\u5185\u901a\u8fc7\u6d88\u606f\u4f20\u9012\u534f\u4f5c\u5b8c\u6210\u4efb\u52a1\u3002Orchestrator \u8d1f\u8d23\u7ba1\u7406 Agent \u95f4\u7684\u6d88\u606f\u8def\u7531\u548c\u7ec8\u6b62\u6761\u4ef6\u3002<\/p>\n<p>\u4f18\u52bf&#xff1a;\u591a Agent \u534f\u4f5c\u6a21\u578b\u5929\u7136\u9002\u5408\u590d\u6742\u4efb\u52a1\u5206\u89e3&#xff1b;\u652f\u6301\u4eba\u7c7b Agent \u53c2\u4e0e&#xff08;Human-in-the-loop&#xff09;&#xff1b;\u5bf9\u8bdd\u5386\u53f2\u81ea\u52a8\u7ba1\u7406\u3002<\/p>\n<p>\u52a3\u52bf&#xff1a;\u9762\u5411\u7814\u7a76\u800c\u975e\u751f\u4ea7&#xff0c;\u7f3a\u4e4f\u6e20\u9053\u9002\u914d\u3001\u9650\u6d41\u3001\u5ba1\u8ba1\u7b49\u751f\u4ea7\u7ea7\u80fd\u529b&#xff1b;\u5355\u8fdb\u7a0b\u6267\u884c&#xff0c;\u65e0\u6c34\u5e73\u6269\u5c55\u65b9\u6848&#xff1b;\u4f1a\u8bdd\u72b6\u6001\u7ba1\u7406\u7b80\u5355&#xff0c;\u65e0\u538b\u7f29\u548c\u9694\u79bb\u673a\u5236\u3002<\/p>\n<h4>8.1.3 CrewAI Manager<\/h4>\n<p>CrewAI \u7684 Manager \u91c7\u7528\u89d2\u8272\u9a71\u52a8\u7684\u8bbe\u8ba1\u54f2\u5b66&#xff0c;\u5c06\u6bcf\u4e2a Agent \u5b9a\u4e49\u4e3a\u5177\u6709\u7279\u5b9a\u89d2\u8272&#xff08;Role&#xff09;\u3001\u76ee\u6807&#xff08;Goal&#xff09;\u548c\u80cc\u666f\u6545\u4e8b&#xff08;Backstory&#xff09;\u7684\u300c\u8239\u5458\u300d\u3002Manager \u8d1f\u8d23\u4efb\u52a1\u5206\u914d\u548c\u8fdb\u5ea6\u7ba1\u7406\u3002<\/p>\n<p>\u4f18\u52bf&#xff1a;\u89d2\u8272\u62bd\u8c61\u76f4\u89c2&#xff0c;\u6613\u4e8e\u7406\u89e3\u548c\u4f7f\u7528&#xff1b;\u4efb\u52a1\u5206\u914d\u7075\u6d3b&#xff0c;\u652f\u6301\u4e32\u884c\u548c\u5e76\u884c&#xff1b;\u5185\u7f6e\u4efb\u52a1\u7ed3\u679c\u9a8c\u8bc1\u673a\u5236\u3002<\/p>\n<p>\u52a3\u52bf&#xff1a;\u7f3a\u4e4f\u72ec\u7acb\u7684 Gateway \u5c42&#xff0c;\u8def\u7531\u903b\u8f91\u4e0e\u4e1a\u52a1\u903b\u8f91\u8026\u5408&#xff1b;\u4e0d\u652f\u6301\u591a\u6e20\u9053\u63a5\u5165&#xff1b;\u65e0\u4f1a\u8bdd\u9694\u79bb\u548c\u4e0a\u4e0b\u6587\u538b\u7f29&#xff1b;\u5de5\u5177\u7ba1\u7406\u7b80\u5355&#xff0c;\u65e0 MCP \u96c6\u6210\u3002<\/p>\n<h4>8.1.4 Hermes Agent Gateway<\/h4>\n<p>Hermes Agent \u7684 Gateway \u91c7\u7528\u7edf\u4e00\u63a7\u5236\u9762\u7684\u8bbe\u8ba1\u54f2\u5b66&#xff0c;\u5c06\u6240\u6709\u63a7\u5236\u903b\u8f91\u2014\u2014\u4f1a\u8bdd\u7ba1\u7406\u3001\u6e20\u9053\u9002\u914d\u3001\u5de5\u5177\u8c03\u5ea6\u3001\u610f\u56fe\u8def\u7531\u2014\u2014\u6536\u655b\u5230\u4e00\u4e2a\u72ec\u7acb\u7684\u4e2d\u67a2\u7ec4\u4ef6&#xff0c;\u901a\u8fc7\u6807\u51c6\u63a5\u53e3\u4e0e\u6570\u636e\u9762\u4ea4\u4e92\u3002<\/p>\n<p>\u6838\u5fc3\u5dee\u5f02&#xff1a;Hermes Gateway \u662f\u552f\u4e00\u5c06\u63a7\u5236\u9762\u4e0e\u6570\u636e\u9762\u5b8c\u5168\u5206\u79bb\u7684\u67b6\u6784&#xff0c;\u8fd9\u4f7f\u5f97\u63a7\u5236\u903b\u8f91\u53ef\u4ee5\u72ec\u7acb\u6f14\u8fdb\u548c\u6269\u5c55&#xff1b;\u552f\u4e00\u5185\u7f6e\u81ea\u8fdb\u5316\u5f15\u64ce\u96c6\u6210\u7684\u67b6\u6784&#xff0c;\u652f\u6301\u7b56\u7565\u7684\u81ea\u52a8\u4f18\u5316\u548c\u70ed\u66f4\u65b0&#xff1b;\u552f\u4e00\u63d0\u4f9b\u5b8c\u6574\u591a\u6e20\u9053\u9002\u914d&#xff08;12&#043;\u5e73\u53f0&#xff09;\u7684\u751f\u4ea7\u7ea7\u67b6\u6784\u3002<\/p>\n<h3>8.2 \u6838\u5fc3\u80fd\u529b\u5bf9\u6bd4\u77e9\u9635<\/h3>\n<table>\n<tr>\u80fd\u529b\u7ef4\u5ea6Hermes GatewayLangChain RouterAutoGen OrchestratorCrewAI Manager<\/tr>\n<tbody>\n<tr>\n<td>\u67b6\u6784\u5b9a\u4f4d<\/td>\n<td>\u7edf\u4e00\u63a7\u5236\u9762<\/td>\n<td>\u94fe\u5f0f\u7ec4\u5408<\/td>\n<td>\u591aAgent\u534f\u4f5c<\/td>\n<td>\u89d2\u8272\u9a71\u52a8<\/td>\n<\/tr>\n<tr>\n<td>\u5f00\u53d1\u8bed\u8a00<\/td>\n<td>Rust &#043; Python<\/td>\n<td>Python<\/td>\n<td>Python<\/td>\n<td>Python<\/td>\n<\/tr>\n<tr>\n<td>\u4f1a\u8bdd\u7ba1\u7406<\/td>\n<td>\u4e09\u5c42\u67b6\u6784&#xff08;\u5de5\u4f5c\/\u77ed\u671f\/\u957f\u671f&#xff09;<\/td>\n<td>\u7b80\u5355\u5185\u5b58\u5b58\u50a8<\/td>\n<td>GroupChat\u5386\u53f2<\/td>\n<td>\u4efb\u52a1\u7ea7\u72b6\u6001<\/td>\n<\/tr>\n<tr>\n<td>\u4e0a\u4e0b\u6587\u538b\u7f29<\/td>\n<td>\u4e09\u7ea7\u538b\u7f29\u7b56\u7565<\/td>\n<td>\u65e0\u5185\u7f6e<\/td>\n<td>\u65e0\u5185\u7f6e<\/td>\n<td>\u65e0\u5185\u7f6e<\/td>\n<\/tr>\n<tr>\n<td>\u5e76\u884c\u4f1a\u8bdd\u9694\u79bb<\/td>\n<td>\u5b8c\u6574\u9694\u79bb\u65b9\u6848<\/td>\n<td>\u65e0<\/td>\n<td>\u65e0<\/td>\n<td>\u65e0<\/td>\n<\/tr>\n<tr>\n<td>\u6e20\u9053\u9002\u914d<\/td>\n<td>12&#043;\u5e73\u53f0\u5185\u7f6e<\/td>\n<td>\u9700\u81ea\u884c\u5b9e\u73b0<\/td>\n<td>\u65e0<\/td>\n<td>\u65e0<\/td>\n<\/tr>\n<tr>\n<td>\u6d88\u606f\u5f52\u4e00\u5316<\/td>\n<td>6\u9636\u6bb5\u7ba1\u7ebf<\/td>\n<td>\u65e0<\/td>\n<td>\u65e0<\/td>\n<td>\u65e0<\/td>\n<\/tr>\n<tr>\n<td>\u5de5\u5177\u6ce8\u518c<\/td>\n<td>\u52a8\u6001\u6ce8\u518c&#043;\u7248\u672c\u7ba1\u7406<\/td>\n<td>\u9759\u6001\u5b9a\u4e49<\/td>\n<td>\u9759\u6001\u5b9a\u4e49<\/td>\n<td>\u9759\u6001\u5b9a\u4e49<\/td>\n<\/tr>\n<tr>\n<td>MCP\u96c6\u6210<\/td>\n<td>\u539f\u751f\u652f\u6301<\/td>\n<td>\u901a\u8fc7\u63d2\u4ef6<\/td>\n<td>\u65e0<\/td>\n<td>\u65e0<\/td>\n<\/tr>\n<tr>\n<td>\u5de5\u5177\u6c99\u7bb1<\/td>\n<td>Firecracker microVM<\/td>\n<td>\u65e0<\/td>\n<td>\u65e0<\/td>\n<td>\u65e0<\/td>\n<\/tr>\n<tr>\n<td>\u6743\u9650\u63a7\u5236<\/td>\n<td>RBAC &#043; \u6761\u4ef6\u63a7\u5236<\/td>\n<td>\u65e0<\/td>\n<td>\u65e0<\/td>\n<td>\u65e0<\/td>\n<\/tr>\n<tr>\n<td>\u8c03\u7528\u5ba1\u8ba1<\/td>\n<td>\u5168\u91cf\u5ba1\u8ba1&#043;\u8131\u654f<\/td>\n<td>\u65e0<\/td>\n<td>\u65e0<\/td>\n<td>\u65e0<\/td>\n<\/tr>\n<tr>\n<td>\u610f\u56fe\u8bc6\u522b<\/td>\n<td>\u4e09\u7ea7\u7ea7\u8054(\u89c4\u5219&#043;ML&#043;LLM)<\/td>\n<td>LLM-based<\/td>\n<td>LLM-based<\/td>\n<td>LLM-based<\/td>\n<\/tr>\n<tr>\n<td>\u4efb\u52a1\u7f16\u6392<\/td>\n<td>\u4e32\u884c\/\u5e76\u884c\/\u6761\u4ef6\/\u5faa\u73af<\/td>\n<td>\u94fe\u5f0f\u4e32\u884c<\/td>\n<td>\u6d88\u606f\u4f20\u9012<\/td>\n<td>\u4e32\u884c\/\u5e76\u884c<\/td>\n<\/tr>\n<tr>\n<td>\u8bb0\u5fc6\u8c03\u5ea6<\/td>\n<td>\u667a\u80fd\u8c03\u5ea6&#043;\u6ce8\u5165<\/td>\n<td>\u624b\u52a8\u7ba1\u7406<\/td>\n<td>\u81ea\u52a8\u4f46\u4e0d\u667a\u80fd<\/td>\n<td>\u65e0<\/td>\n<\/tr>\n<tr>\n<td>\u81ea\u8fdb\u5316<\/td>\n<td>\u5185\u7f6e\u96c6\u6210<\/td>\n<td>\u65e0<\/td>\n<td>\u65e0<\/td>\n<td>\u65e0<\/td>\n<\/tr>\n<tr>\n<td>\u6c34\u5e73\u6269\u5c55<\/td>\n<td>\u65e0\u72b6\u6001&#043;\u4e00\u81f4\u6027\u54c8\u5e0c<\/td>\n<td>\u65e0<\/td>\n<td>\u65e0<\/td>\n<td>\u65e0<\/td>\n<\/tr>\n<tr>\n<td>\u6545\u969c\u6062\u590d<\/td>\n<td>\u81ea\u52a8\u6545\u969c\u8f6c\u79fb<\/td>\n<td>\u65e0<\/td>\n<td>\u65e0<\/td>\n<td>\u65e0<\/td>\n<\/tr>\n<tr>\n<td>\u53ef\u89c2\u6d4b\u6027<\/td>\n<td>\u5168\u94fe\u8def\u8ffd\u8e2a&#043;\u6307\u6807&#043;\u65e5\u5fd7<\/td>\n<td>\u57fa\u7840\u65e5\u5fd7<\/td>\n<td>\u57fa\u7840\u65e5\u5fd7<\/td>\n<td>\u57fa\u7840\u65e5\u5fd7<\/td>\n<\/tr>\n<tr>\n<td>\u914d\u7f6e\u7ba1\u7406<\/td>\n<td>\u58f0\u660e\u5f0f&#043;\u70ed\u66f4\u65b0<\/td>\n<td>\u4ee3\u7801\u914d\u7f6e<\/td>\n<td>\u4ee3\u7801\u914d\u7f6e<\/td>\n<td>\u4ee3\u7801\u914d\u7f6e<\/td>\n<\/tr>\n<tr>\n<td>\u751f\u4ea7\u5c31\u7eea<\/td>\n<td>\u662f<\/td>\n<td>\u90e8\u5206<\/td>\n<td>\u5426<\/td>\n<td>\u5426<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>8.3 \u573a\u666f\u9002\u7528\u6027\u5206\u6790<\/h3>\n<h4>8.3.1 \u9002\u7528\u573a\u666f\u5bf9\u6bd4<\/h4>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502                    \u573a\u666f\u9002\u7528\u6027\u96f7\u8fbe\u56fe                                     \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502                    \u591a\u6e20\u9053\u63a5\u5165                                          \u2502<br \/>\n\u2502                         5                                             \u2502<br \/>\n\u2502                    4   \u2502   5  Hermes                                  \u2502<br \/>\n\u2502               3        \u2502        4  LangChain                         \u2502<br \/>\n\u2502          2             \u2502             3  AutoGen                      \u2502<br \/>\n\u2502      1                 \u2502                  2  CrewAI                  \u2502<br \/>\n\u2502  \u751f\u4ea7\u7ea7\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u9ad8\u5e76\u53d1                     \u2502<br \/>\n\u2502      1                 \u2502                  2                          \u2502<br \/>\n\u2502          2             \u2502             3                               \u2502<br \/>\n\u2502               3        \u2502        4                                    \u2502<br \/>\n\u2502                    4   \u2502   5                                          \u2502<br \/>\n\u2502                         5                                             \u2502<br \/>\n\u2502              \u591aAgent\u534f\u4f5c          \u5de5\u5177\u751f\u6001                              \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  \u8bc4\u5206\u6807\u51c6: 1&#061;\u4e0d\u652f\u6301 2&#061;\u57fa\u7840 3&#061;\u53ef\u7528 4&#061;\u4f18\u79c0 5&#061;\u5353\u8d8a                        \u2502<br \/>\n\u2502                                                                      \u2502<br \/>\n\u2502  Hermes Agent:  \u751f\u4ea75 | \u591a\u6e20\u90535 | \u9ad8\u5e76\u53d15 | \u591aAgent3 | \u5de5\u5177\u751f\u60014      \u2502<br \/>\n\u2502  LangChain:     \u751f\u4ea73 | \u591a\u6e20\u90532 | \u9ad8\u5e76\u53d12 | \u591aAgent3 | \u5de5\u5177\u751f\u60015      \u2502<br \/>\n\u2502  AutoGen:       \u751f\u4ea72 | \u591a\u6e20\u90531 | \u9ad8\u5e76\u53d11 | \u591aAgent5 | \u5de5\u5177\u751f\u60013      \u2502<br \/>\n\u2502  CrewAI:        \u751f\u4ea72 | \u591a\u6e20\u90531 | \u9ad8\u5e76\u53d11 | \u591aAgent4 | \u5de5\u5177\u751f\u60013      \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<h4>8.3.2 \u9009\u578b\u5efa\u8bae<\/h4>\n<table>\n<tr>\u573a\u666f\u63a8\u8350\u6846\u67b6\u63a8\u8350\u7406\u7531<\/tr>\n<tbody>\n<tr>\n<td>\u4f01\u4e1a\u7ea7\u591a\u6e20\u9053 Agent \u5e73\u53f0<\/td>\n<td>Hermes Agent<\/td>\n<td>\u5b8c\u6574\u7684\u591a\u6e20\u9053\u9002\u914d\u3001\u4f1a\u8bdd\u7ba1\u7406\u3001\u6743\u9650\u63a7\u5236\u548c\u6c34\u5e73\u6269\u5c55\u80fd\u529b<\/td>\n<\/tr>\n<tr>\n<td>\u5feb\u901f\u539f\u578b\u5f00\u53d1<\/td>\n<td>LangChain<\/td>\n<td>\u4e30\u5bcc\u7684\u9884\u7f6e\u7ec4\u4ef6\u548c\u793e\u533a\u751f\u6001&#xff0c;\u6700\u5feb\u642d\u5efa\u53ef\u7528\u7684 Agent<\/td>\n<\/tr>\n<tr>\n<td>\u591a Agent \u534f\u4f5c\u7814\u7a76<\/td>\n<td>AutoGen<\/td>\n<td>\u539f\u751f\u7684\u591a Agent \u5bf9\u8bdd\u673a\u5236&#xff0c;\u9002\u5408\u7814\u7a76 Agent \u95f4\u534f\u4f5c\u6a21\u5f0f<\/td>\n<\/tr>\n<tr>\n<td>\u89d2\u8272\u626e\u6f14\u578b Agent<\/td>\n<td>CrewAI<\/td>\n<td>\u89d2\u8272\u62bd\u8c61\u76f4\u89c2&#xff0c;\u9002\u5408\u9700\u8981\u591a\u89d2\u8272\u5206\u5de5\u7684\u573a\u666f<\/td>\n<\/tr>\n<tr>\n<td>\u9ad8\u5e76\u53d1\u751f\u4ea7\u90e8\u7f72<\/td>\n<td>Hermes Agent<\/td>\n<td>Rust \u6838\u5fc3 &#043; \u65e0\u72b6\u6001\u8bbe\u8ba1 &#043; \u81ea\u52a8\u4f38\u7f29&#xff0c;\u652f\u6491\u9ad8\u5e76\u53d1<\/td>\n<\/tr>\n<tr>\n<td>\u5de5\u5177\u5bc6\u96c6\u578b\u4efb\u52a1<\/td>\n<td>Hermes Agent<\/td>\n<td>\u5b8c\u6574\u7684\u5de5\u5177\u6ce8\u518c\u8868 &#043; MCP \u96c6\u6210 &#043; \u6c99\u7bb1\u9694\u79bb<\/td>\n<\/tr>\n<tr>\n<td>\u6559\u80b2\u548c\u6f14\u793a<\/td>\n<td>LangChain \/ CrewAI<\/td>\n<td>\u4e0a\u624b\u95e8\u69db\u4f4e&#xff0c;\u4ee3\u7801\u91cf\u5c11&#xff0c;\u6613\u4e8e\u7406\u89e3<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>8.3.3 \u6f14\u8fdb\u8d8b\u52bf<\/h4>\n<p>\u4ece\u67b6\u6784\u6f14\u8fdb\u7684\u89d2\u5ea6\u770b&#xff0c;Agent \u6846\u67b6\u7684 Gateway \u5c42\u6b63\u5728\u7ecf\u5386\u4ee5\u4e0b\u8d8b\u52bf&#xff1a;<\/p>\n<li>\n<p>\u63a7\u5236\u9762\/\u6570\u636e\u9762\u5206\u79bb&#xff1a;\u4ece LangChain \u7684\u94fe\u5f0f\u8026\u5408&#xff0c;\u5230 Hermes \u7684\u63a7\u5236\u9762\u72ec\u7acb&#xff0c;\u5206\u79bb\u8d8b\u52bf\u660e\u663e\u3002\u8fd9\u4f7f\u5f97\u63a7\u5236\u903b\u8f91\u53ef\u4ee5\u72ec\u7acb\u6269\u5c55\u548c\u6f14\u8fdb\u3002<\/p>\n<\/li>\n<li>\n<p>\u591a\u6e20\u9053\u539f\u751f\u652f\u6301&#xff1a;\u968f\u7740 Agent \u4ece\u5f00\u53d1\u5de5\u5177\u8d70\u5411\u751f\u4ea7\u7cfb\u7edf&#xff0c;\u591a\u6e20\u9053\u63a5\u5165&#xff08;IM\u3001Web\u3001API\u3001\u8bed\u97f3&#xff09;\u6210\u4e3a\u5fc5\u5907\u80fd\u529b\u3002Hermes \u7684 12&#043; \u5e73\u53f0\u9002\u914d\u5668\u662f\u8fd9\u4e00\u8d8b\u52bf\u7684\u4f53\u73b0\u3002<\/p>\n<\/li>\n<li>\n<p>\u8bb0\u5fc6\u7cfb\u7edf\u667a\u80fd\u5316&#xff1a;\u4ece\u7b80\u5355\u7684\u5bf9\u8bdd\u5386\u53f2\u5b58\u50a8&#xff0c;\u5230\u4e09\u5c42\u8bb0\u5fc6\u67b6\u6784 &#043; \u667a\u80fd\u8c03\u5ea6&#xff0c;\u8bb0\u5fc6\u7cfb\u7edf\u6b63\u5728\u6210\u4e3a Agent \u7684\u6838\u5fc3\u5dee\u5f02\u5316\u80fd\u529b\u3002<\/p>\n<\/li>\n<li>\n<p>\u81ea\u8fdb\u5316\u80fd\u529b&#xff1a;\u4ece\u9759\u6001\u914d\u7f6e\u5230\u52a8\u6001\u4f18\u5316&#xff0c;\u81ea\u8fdb\u5316\u5f15\u64ce\u4f7f\u5f97 Agent \u7cfb\u7edf\u80fd\u591f\u57fa\u4e8e\u8fd0\u884c\u6570\u636e\u6301\u7eed\u6539\u8fdb\u8def\u7531\u7b56\u7565\u548c\u53c2\u6570\u914d\u7f6e\u3002<\/p>\n<\/li>\n<li>\n<p>\u751f\u4ea7\u7ea7\u7279\u6027&#xff1a;\u6743\u9650\u63a7\u5236\u3001\u8c03\u7528\u5ba1\u8ba1\u3001\u6545\u969c\u6062\u590d\u3001\u6c34\u5e73\u6269\u5c55\u7b49\u751f\u4ea7\u7ea7\u7279\u6027\u6b63\u5728\u4ece\u300c\u52a0\u5206\u9879\u300d\u53d8\u4e3a\u300c\u5fc5\u9009\u9879\u300d\u3002<\/p>\n<\/li>\n<li>\n<p>MCP \u6807\u51c6\u5316&#xff1a;MCP \u534f\u8bae\u6b63\u5728\u6210\u4e3a\u5de5\u5177\u5c42\u7684\u7edf\u4e00\u6807\u51c6&#xff0c;\u672a\u6765 Agent \u6846\u67b6\u7684\u5de5\u5177\u751f\u6001\u5c06\u56f4\u7ed5 MCP \u5c55\u5f00\u3002<\/p>\n<\/li>\n<hr \/>\n<h3>\u9644\u5f55 A&#xff1a;\u672f\u8bed\u8868<\/h3>\n<table>\n<tr>\u672f\u8bed\u5168\u79f0\u8bf4\u660e<\/tr>\n<tbody>\n<tr>\n<td>Gateway<\/td>\n<td>&#8211;<\/td>\n<td>\u7edf\u4e00\u63a7\u5236\u9762&#xff0c;Hermes Agent \u7684\u4e2d\u67a2\u7ec4\u4ef6<\/td>\n<\/tr>\n<tr>\n<td>SPI<\/td>\n<td>Service Provider Interface<\/td>\n<td>\u670d\u52a1\u63d0\u4f9b\u8005\u63a5\u53e3&#xff0c;\u53ef\u63d2\u62d4\u7ec4\u4ef6\u7684\u6807\u51c6\u63a5\u53e3<\/td>\n<\/tr>\n<tr>\n<td>WAL<\/td>\n<td>Write-Ahead Log<\/td>\n<td>\u9884\u5199\u65e5\u5fd7&#xff0c;\u4fdd\u8bc1\u6570\u636e\u66f4\u65b0\u539f\u5b50\u6027\u7684\u673a\u5236<\/td>\n<\/tr>\n<tr>\n<td>MCP<\/td>\n<td>Model Context Protocol<\/td>\n<td>\u6a21\u578b\u4e0a\u4e0b\u6587\u534f\u8bae&#xff0c;Anthropic \u63d0\u51fa\u7684\u5f00\u653e\u6807\u51c6<\/td>\n<\/tr>\n<tr>\n<td>RBAC<\/td>\n<td>Role-Based Access Control<\/td>\n<td>\u57fa\u4e8e\u89d2\u8272\u7684\u8bbf\u95ee\u63a7\u5236<\/td>\n<\/tr>\n<tr>\n<td>HPA<\/td>\n<td>Horizontal Pod Autoscaler<\/td>\n<td>Kubernetes \u6c34\u5e73 Pod \u81ea\u52a8\u4f38\u7f29\u5668<\/td>\n<\/tr>\n<tr>\n<td>microVM<\/td>\n<td>Micro Virtual Machine<\/td>\n<td>\u5fae\u865a\u62df\u673a&#xff0c;\u8f7b\u91cf\u7ea7\u9694\u79bb\u6280\u672f<\/td>\n<\/tr>\n<tr>\n<td>Phi Accusal<\/td>\n<td>&#8211;<\/td>\n<td>\u57fa\u4e8e Phi \u503c\u7684\u6545\u969c\u68c0\u6d4b\u7b97\u6cd5<\/td>\n<\/tr>\n<tr>\n<td>SSE<\/td>\n<td>Server-Sent Events<\/td>\n<td>\u670d\u52a1\u5668\u53d1\u9001\u4e8b\u4ef6&#xff0c;\u6d41\u5f0f\u901a\u4fe1\u534f\u8bae<\/td>\n<\/tr>\n<tr>\n<td>LCEL<\/td>\n<td>LangChain Expression Language<\/td>\n<td>LangChain \u8868\u8fbe\u5f0f\u8bed\u8a00<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>\u9644\u5f55 B&#xff1a;\u914d\u7f6e\u53c2\u6570\u901f\u67e5<\/h3>\n<table>\n<tr>\u53c2\u6570\u9ed8\u8ba4\u503c\u8bf4\u660e\u8c03\u4f18\u5efa\u8bae<\/tr>\n<tbody>\n<tr>\n<td>worker_threads<\/td>\n<td>CPU\u6838\u6570<\/td>\n<td>Tokio\u5de5\u4f5c\u7ebf\u7a0b\u6570<\/td>\n<td>IO\u5bc6\u96c6\u578b\u4fdd\u6301\u9ed8\u8ba4&#xff0c;CPU\u5bc6\u96c6\u578b\u53ef\u589e\u52a0<\/td>\n<\/tr>\n<tr>\n<td>max_connections<\/td>\n<td>10000<\/td>\n<td>\u6700\u5927\u8fde\u63a5\u6570<\/td>\n<td>\u6839\u636e\u5185\u5b58\u8c03\u6574&#xff0c;\u6bcf\u4e2a\u8fde\u63a5\u7ea64KB<\/td>\n<\/tr>\n<tr>\n<td>session.default_ttl<\/td>\n<td>3600s<\/td>\n<td>\u4f1a\u8bdd\u9ed8\u8ba4\u5b58\u6d3b\u65f6\u95f4<\/td>\n<td>\u6839\u636e\u4e1a\u52a1\u573a\u666f\u8c03\u6574<\/td>\n<\/tr>\n<tr>\n<td>session.max_concurrent_per_user<\/td>\n<td>5<\/td>\n<td>\u6bcf\u7528\u6237\u6700\u5927\u5e76\u53d1\u4f1a\u8bdd<\/td>\n<td>\u9632\u6b62\u5355\u7528\u6237\u8d44\u6e90\u5360\u7528<\/td>\n<\/tr>\n<tr>\n<td>context_window.max_tokens<\/td>\n<td>32768<\/td>\n<td>\u4e0a\u4e0b\u6587\u7a97\u53e3\u5927\u5c0f<\/td>\n<td>\u6839\u636e\u4f7f\u7528\u7684\u6a21\u578b\u8c03\u6574<\/td>\n<\/tr>\n<tr>\n<td>compression_threshold<\/td>\n<td>0.75<\/td>\n<td>\u538b\u7f29\u89e6\u53d1\u9608\u503c<\/td>\n<td>\u964d\u4f4e\u5219\u66f4\u9891\u7e41\u538b\u7f29&#xff0c;\u589e\u52a0Token\u5229\u7528\u7387<\/td>\n<\/tr>\n<tr>\n<td>routing.max_orchestration_depth<\/td>\n<td>8<\/td>\n<td>\u6700\u5927\u7f16\u6392\u6df1\u5ea6<\/td>\n<td>\u9632\u6b62\u65e0\u9650\u9012\u5f52<\/td>\n<\/tr>\n<tr>\n<td>routing.parallel_task_limit<\/td>\n<td>4<\/td>\n<td>\u5e76\u884c\u4efb\u52a1\u4e0a\u9650<\/td>\n<td>\u6839\u636e\u4e0b\u6e38\u670d\u52a1\u627f\u53d7\u80fd\u529b\u8c03\u6574<\/td>\n<\/tr>\n<tr>\n<td>tools.sandbox.memory_limit<\/td>\n<td>512MB<\/td>\n<td>\u6c99\u7bb1\u5185\u5b58\u9650\u5236<\/td>\n<td>\u6839\u636e\u4ee3\u7801\u6267\u884c\u9700\u6c42\u8c03\u6574<\/td>\n<\/tr>\n<tr>\n<td>tools.sandbox.timeout<\/td>\n<td>30s<\/td>\n<td>\u6c99\u7bb1\u6267\u884c\u8d85\u65f6<\/td>\n<td>\u9632\u6b62\u6076\u610f\u957f\u65f6\u95f4\u6267\u884c<\/td>\n<\/tr>\n<tr>\n<td>observability.tracing.sampling_rate<\/td>\n<td>0.1<\/td>\n<td>\u8ffd\u8e2a\u91c7\u6837\u7387<\/td>\n<td>\u751f\u4ea7\u73af\u5883\u5efa\u8bae0.01-0.1<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<h3>\u9644\u5f55 C&#xff1a;Gateway \u8bf7\u6c42\u5904\u7406\u5168\u94fe\u8def\u8ffd\u8e2a\u793a\u4f8b<\/h3>\n<p>\u4ee5\u4e0b\u662f\u4e00\u6b21\u5b8c\u6574\u8bf7\u6c42\u7684\u5904\u7406\u94fe\u8def&#xff0c;\u5c55\u793a\u4e86 Gateway \u5404\u7ec4\u4ef6\u7684\u534f\u4f5c\u65f6\u5e8f&#xff1a;<\/p>\n<p>\u65f6\u95f4\u7ebf (\u6beb\u79d2)<br \/>\n  \u2502<br \/>\n  0ms  \u2500\u2500&gt; [\u63a5\u5165\u5c42] \u6536\u5230 HTTP \u8bf7\u6c42 (POST \/api\/chat)<br \/>\n  0.5ms \u2500\u2500&gt; [\u63a5\u5165\u5c42] TLS \u7ec8\u6b62 &#043; \u8bf7\u6c42\u89e3\u6790<br \/>\n  1ms   \u2500\u2500&gt; [\u9002\u914d\u5c42] WebAdapter.receive_message()<br \/>\n  1.5ms \u2500\u2500&gt; [\u5f52\u4e00\u5316] \u5b89\u5168\u9a8c\u8bc1 \u2192 \u9891\u7387\u9650\u5236\u68c0\u67e5\u901a\u8fc7<br \/>\n  2ms   \u2500\u2500&gt; [\u5f52\u4e00\u5316] \u683c\u5f0f\u89e3\u6790 \u2192 JSON \u89e3\u6790\u6210\u529f<br \/>\n  2.5ms \u2500\u2500&gt; [\u5f52\u4e00\u5316] \u5185\u5bb9\u5f52\u4e00\u5316 \u2192 \u6587\u672c\u63d0\u53d6\u5b8c\u6210<br \/>\n  3ms   \u2500\u2500&gt; [\u5f52\u4e00\u5316] \u5185\u5bb9\u589e\u5f3a \u2192 \u8bed\u8a00\u68c0\u6d4b:zh, \u610f\u56fe\u9884\u5224:data_analysis<br \/>\n  3.5ms \u2500\u2500&gt; [\u5f52\u4e00\u5316] \u4f1a\u8bdd\u89e3\u6790 \u2192 session_id: 0x3F&#8230;A1<br \/>\n  4ms   \u2500\u2500&gt; [\u4f1a\u8bdd\u5c42] \u52a0\u8f7d\u4f1a\u8bdd\u4e0a\u4e0b\u6587 (Redis GET)<br \/>\n  5ms   \u2500\u2500&gt; [\u4f1a\u8bdd\u5c42] \u4e0a\u4e0b\u6587\u52a0\u8f7d\u5b8c\u6210 (12\u8f6e\u5386\u53f2)<br \/>\n  \u2502<br \/>\n  5.5ms \u2500\u2500&gt; [\u8def\u7531\u5c42] \u610f\u56fe\u8bc6\u522b Level 1 (\u89c4\u5219\u5339\u914d) \u2192 \u7f6e\u4fe1\u5ea6 0.6<br \/>\n  6ms   \u2500\u2500&gt; [\u8def\u7531\u5c42] \u610f\u56fe\u8bc6\u522b Level 2 (ML\u6a21\u578b) \u2192 \u7f6e\u4fe1\u5ea6 0.82<br \/>\n  6.5ms \u2500\u2500&gt; [\u8def\u7531\u5c42] \u610f\u56fe\u8bc6\u522b Level 3 (LLM\u63a8\u7406) \u2192 \u7f6e\u4fe1\u5ea6 0.95<br \/>\n  \u2502           \u610f\u56fe: data_analysis, \u5de5\u5177: [http_request, code_execution, web_search]<br \/>\n  \u2502<br \/>\n  7ms   \u2500\u2500&gt; [\u8def\u7531\u5c42] \u521b\u5efa\u6267\u884c\u8ba1\u5212 (6\u6b65: 2\u5e76\u884c&#043;4\u4e32\u884c)<br \/>\n  \u2502<br \/>\n  7.5ms \u2500\u2500&gt; [\u8bb0\u5fc6\u5c42] \u8bb0\u5fc6\u8c03\u5ea6\u51b3\u7b56: \u8bfb\u5de5\u4f5c&#043;\u77ed\u671f&#043;\u957f\u671f<br \/>\n  8ms   \u2500\u2500&gt; [\u8bb0\u5fc6\u5c42] \u5e76\u884c\u8bfb\u53d6\u8bb0\u5fc6<br \/>\n  12ms  \u2500\u2500&gt; [\u8bb0\u5fc6\u5c42] \u8bb0\u5fc6\u8bfb\u53d6\u5b8c\u6210 (\u5de5\u4f5c:5ms, \u77ed\u671f:4ms, \u957f\u671f:7ms)<br \/>\n  13ms  \u2500\u2500&gt; [\u8bb0\u5fc6\u5c42] \u8bb0\u5fc6\u6ce8\u5165\u4e0a\u4e0b\u6587 (450 tokens)<br \/>\n  \u2502<br \/>\n  14ms  \u2500\u2500&gt; [\u7f16\u6392\u5c42] \u5e76\u884c\u542f\u52a8 Step 1 (fetch_data) &#043; Step 3 (search_benchmarks)<br \/>\n  \u2502<br \/>\n  14ms  \u2500\u2500&gt; [\u5de5\u5177\u5c42] Step 1: HTTP\u8bf7\u6c42\u5de5\u5177\u8c03\u7528<br \/>\n  145ms \u2500\u2500&gt; [\u5de5\u5177\u5c42] Step 1 \u5b8c\u6210 (\u5ef6\u8fdf: 131ms)<br \/>\n  \u2502<br \/>\n  14ms  \u2500\u2500&gt; [\u5de5\u5177\u5c42] Step 3: Web\u641c\u7d22\u5de5\u5177\u8c03\u7528<br \/>\n  89ms  \u2500\u2500&gt; [\u5de5\u5177\u5c42] Step 3 \u5b8c\u6210 (\u5ef6\u8fdf: 75ms)<br \/>\n  \u2502<br \/>\n  145ms \u2500\u2500&gt; [\u7f16\u6392\u5c42] Step 2: \u4ee3\u7801\u6267\u884c (\u4f9d\u8d56 Step 1)<br \/>\n  145ms \u2500\u2500&gt; [\u5de5\u5177\u5c42] \u6c99\u7bb1\u83b7\u53d6 (\u6c60\u4e2d\u9884\u70ed\u5b9e\u4f8b)<br \/>\n  152ms \u2500\u2500&gt; [\u5de5\u5177\u5c42] \u4ee3\u7801\u6267\u884c\u5f00\u59cb<br \/>\n  185ms \u2500\u2500&gt; [\u5de5\u5177\u5c42] Step 2 \u5b8c\u6210 (\u5ef6\u8fdf: 40ms)<br \/>\n  \u2502<br \/>\n  185ms \u2500\u2500&gt; [\u7f16\u6392\u5c42] Step 4: LLM\u5206\u6790 (\u4f9d\u8d56 Step 2 &#043; Step 3)<br \/>\n  185ms \u2500\u2500&gt; [\u6a21\u578b\u5c42] \u6a21\u578b\u8def\u7531\u5668\u9009\u62e9: claude-3.5-sonnet<br \/>\n  190ms \u2500\u2500&gt; [\u6a21\u578b\u5c42] \u63a8\u7406\u8bf7\u6c42\u53d1\u51fa<br \/>\n  \u2502<br \/>\n  190ms \u2500\u2500&gt; [\u6a21\u578b\u5c42] \u6d41\u5f0f\u54cd\u5e94\u5f00\u59cb<br \/>\n  190ms \u2500\u2500&gt; [\u9002\u914d\u5c42] \u6d41\u5f0f\u8f93\u51fa\u5f00\u59cb (SSE)<br \/>\n  &#8230;        (\u9010 token \u6d41\u5f0f\u8f93\u51fa)<br \/>\n  2150ms \u2500\u2500&gt; [\u6a21\u578b\u5c42] \u6d41\u5f0f\u54cd\u5e94\u5b8c\u6210<br \/>\n  \u2502<br \/>\n  2150ms \u2500\u2500&gt; [\u7f16\u6392\u5c42] \u5e76\u884c\u542f\u52a8 Step 5 (\u8bb0\u5fc6\u5199\u5165) &#043; Step 6 (\u62a5\u544a\u751f\u6210)<br \/>\n  2155ms \u2500\u2500&gt; [\u8bb0\u5fc6\u5c42] Step 5: \u8bb0\u5fc6\u5199\u5165\u5b8c\u6210<br \/>\n  2180ms \u2500\u2500&gt; [\u6a21\u578b\u5c42] Step 6: \u62a5\u544a\u751f\u6210\u5b8c\u6210<br \/>\n  \u2502<br \/>\n  2180ms \u2500\u2500&gt; [\u4f1a\u8bdd\u5c42] \u66f4\u65b0\u4f1a\u8bdd\u4e0a\u4e0b\u6587<br \/>\n  2185ms \u2500\u2500&gt; [\u4f1a\u8bdd\u5c42] \u4e0a\u4e0b\u6587\u66f4\u65b0\u5b8c\u6210 (13\u8f6e)<br \/>\n  \u2502<br \/>\n  2185ms \u2500\u2500&gt; [\u5ba1\u8ba1\u5c42] \u8bb0\u5f55\u5de5\u5177\u8c03\u7528\u5ba1\u8ba1\u65e5\u5fd7 (3\u4e2a\u5de5\u5177\u8c03\u7528)<br \/>\n  2187ms \u2500\u2500&gt; [\u5ba1\u8ba1\u5c42] \u5ba1\u8ba1\u65e5\u5fd7\u5199\u5165\u5b8c\u6210<br \/>\n  \u2502<br \/>\n  2187ms \u2500\u2500&gt; [\u53ef\u89c2\u6d4b] \u4e0a\u62a5\u6307\u6807 (\u5ef6\u8fdf\u3001Token\u3001\u5de5\u5177\u8c03\u7528)<br \/>\n  2190ms \u2500\u2500&gt; [\u63a5\u5165\u5c42] \u54cd\u5e94\u53d1\u9001\u5b8c\u6210<br \/>\n  \u2502<br \/>\n  \u603b\u5ef6\u8fdf: 2190ms<br \/>\n  \u00b7 Gateway \u5185\u90e8\u5904\u7406: 305ms (14%)<br \/>\n  \u00b7 \u5de5\u5177\u8c03\u7528: 246ms (11%)<br \/>\n  \u00b7 \u6a21\u578b\u63a8\u7406: 1990ms (91%)<br \/>\n  \u00b7 I\/O \u7b49\u5f85: \u5e76\u884c\u5316\u540e\u5df2\u6700\u5c0f\u5316<\/p>\n<hr \/>\n<p>\u7f16\u5199\u65f6\u95f4 2026-07-07 | \u7f16\u5199\u8005&#xff1a;\u98ce\u4e91\u518d\u8d77<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Gateway\u7edf\u4e00\u63a7\u5236\u9762\u67b6\u6784\u6df1\u5ea6\u89e3\u6790 \u6587\u6863\u5b9a\u4f4d&#xff1a;\u672c\u6587\u6863\u662f Hermes Agent \u81ea\u8fdb\u5316\u667a\u80fd\u4f53\u9ad8\u9636\u5b9e\u6218\u77e5\u8bc6\u4f53\u7cfb\u4e2d\u300c\u4ea7\u54c1\u5b9a\u4f4d\u4e0e\u6838\u5fc3\u67b6\u6784\u300d\u7ae0\u8282\u7684\u7b2c\u4e8c\u4e2a\u62c6\u89e3\u70b9&#xff0c;\u805a\u7126\u4e8e Gateway \u7edf\u4e00\u63a7\u5236\u9762\u7684\u67b6\u6784\u8bbe\u8ba1\u3001\u6838\u5fc3\u673a\u5236\u4e0e\u5de5\u7a0b\u5b9e\u73b0\u3002 \u9002\u7528\u8bfb\u8005&#xff1a;\u67b6\u6784\u8bbe\u8ba1\u4eba\u5458\u3001AI Agent \u5e73\u53f0\u5f00\u53d1\u8005\u3001\u540e\u7aef\u9ad8\u7ea7\u5de5\u7a0b\u5e08\u3001\u6280\u672f\u51b3\u7b56\u8005 \u524d\u7f6e\u4f9d\u8d56&#xff1a;\u5efa\u8bae\u5148\u9605\u8bfb\u300a01_\u4ea7\u54c1\u5b9a\u4f4d\u4e0e\u7cfb\u7edf\u5168\u666f\u300b\u4ee5\u5efa\u7acb\u6574\u4f53\u8ba4\u77e5\u6846\u67b6 &#x1f449;\u5199\u535a\u5ba2\u7684\u670b\u53cb\u53ef\u4ee5\u770b\u770b\u8fd9\u4e2a&amp;#xf<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[10239,10241,10240,1418,188],"topic":[],"class_list":["post-90019","post","type-post","status-publish","format-standard","hentry","category-server","tag-hermes-agent","tag-10241","tag-10240","tag-gateway","tag-188"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Hermes Agent Gateway\u7edf\u4e00\u63a7\u5236\u9762\u67b6\u6784\u6df1\u5ea6\u89e3\u6790 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.wsisp.com\/helps\/90019.html\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Hermes Agent Gateway\u7edf\u4e00\u63a7\u5236\u9762\u67b6\u6784\u6df1\u5ea6\u89e3\u6790 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"og:description\" content=\"Gateway\u7edf\u4e00\u63a7\u5236\u9762\u67b6\u6784\u6df1\u5ea6\u89e3\u6790 \u6587\u6863\u5b9a\u4f4d&#xff1a;\u672c\u6587\u6863\u662f Hermes Agent \u81ea\u8fdb\u5316\u667a\u80fd\u4f53\u9ad8\u9636\u5b9e\u6218\u77e5\u8bc6\u4f53\u7cfb\u4e2d\u300c\u4ea7\u54c1\u5b9a\u4f4d\u4e0e\u6838\u5fc3\u67b6\u6784\u300d\u7ae0\u8282\u7684\u7b2c\u4e8c\u4e2a\u62c6\u89e3\u70b9&#xff0c;\u805a\u7126\u4e8e Gateway \u7edf\u4e00\u63a7\u5236\u9762\u7684\u67b6\u6784\u8bbe\u8ba1\u3001\u6838\u5fc3\u673a\u5236\u4e0e\u5de5\u7a0b\u5b9e\u73b0\u3002 \u9002\u7528\u8bfb\u8005&#xff1a;\u67b6\u6784\u8bbe\u8ba1\u4eba\u5458\u3001AI Agent \u5e73\u53f0\u5f00\u53d1\u8005\u3001\u540e\u7aef\u9ad8\u7ea7\u5de5\u7a0b\u5e08\u3001\u6280\u672f\u51b3\u7b56\u8005 \u524d\u7f6e\u4f9d\u8d56&#xff1a;\u5efa\u8bae\u5148\u9605\u8bfb\u300a01_\u4ea7\u54c1\u5b9a\u4f4d\u4e0e\u7cfb\u7edf\u5168\u666f\u300b\u4ee5\u5efa\u7acb\u6574\u4f53\u8ba4\u77e5\u6846\u67b6 &#x1f449;\u5199\u535a\u5ba2\u7684\u670b\u53cb\u53ef\u4ee5\u770b\u770b\u8fd9\u4e2a&amp;#xf\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.wsisp.com\/helps\/90019.html\" \/>\n<meta property=\"og:site_name\" content=\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-04T06:57:23+00:00\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"84 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/90019.html\",\"url\":\"https:\/\/www.wsisp.com\/helps\/90019.html\",\"name\":\"Hermes Agent Gateway\u7edf\u4e00\u63a7\u5236\u9762\u67b6\u6784\u6df1\u5ea6\u89e3\u6790 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"isPartOf\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\"},\"datePublished\":\"2026-08-04T06:57:23+00:00\",\"dateModified\":\"2026-08-04T06:57:23+00:00\",\"author\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/90019.html#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.wsisp.com\/helps\/90019.html\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/90019.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.wsisp.com\/helps\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Hermes Agent Gateway\u7edf\u4e00\u63a7\u5236\u9762\u67b6\u6784\u6df1\u5ea6\u89e3\u6790\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\",\"url\":\"https:\/\/www.wsisp.com\/helps\/\",\"name\":\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"description\":\"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"contentUrl\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"caption\":\"admin\"},\"sameAs\":[\"http:\/\/wp.wsisp.com\"],\"url\":\"https:\/\/www.wsisp.com\/helps\/author\/admin\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Hermes Agent Gateway\u7edf\u4e00\u63a7\u5236\u9762\u67b6\u6784\u6df1\u5ea6\u89e3\u6790 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.wsisp.com\/helps\/90019.html","og_locale":"zh_CN","og_type":"article","og_title":"Hermes Agent Gateway\u7edf\u4e00\u63a7\u5236\u9762\u67b6\u6784\u6df1\u5ea6\u89e3\u6790 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","og_description":"Gateway\u7edf\u4e00\u63a7\u5236\u9762\u67b6\u6784\u6df1\u5ea6\u89e3\u6790 \u6587\u6863\u5b9a\u4f4d&#xff1a;\u672c\u6587\u6863\u662f Hermes Agent \u81ea\u8fdb\u5316\u667a\u80fd\u4f53\u9ad8\u9636\u5b9e\u6218\u77e5\u8bc6\u4f53\u7cfb\u4e2d\u300c\u4ea7\u54c1\u5b9a\u4f4d\u4e0e\u6838\u5fc3\u67b6\u6784\u300d\u7ae0\u8282\u7684\u7b2c\u4e8c\u4e2a\u62c6\u89e3\u70b9&#xff0c;\u805a\u7126\u4e8e Gateway \u7edf\u4e00\u63a7\u5236\u9762\u7684\u67b6\u6784\u8bbe\u8ba1\u3001\u6838\u5fc3\u673a\u5236\u4e0e\u5de5\u7a0b\u5b9e\u73b0\u3002 \u9002\u7528\u8bfb\u8005&#xff1a;\u67b6\u6784\u8bbe\u8ba1\u4eba\u5458\u3001AI Agent \u5e73\u53f0\u5f00\u53d1\u8005\u3001\u540e\u7aef\u9ad8\u7ea7\u5de5\u7a0b\u5e08\u3001\u6280\u672f\u51b3\u7b56\u8005 \u524d\u7f6e\u4f9d\u8d56&#xff1a;\u5efa\u8bae\u5148\u9605\u8bfb\u300a01_\u4ea7\u54c1\u5b9a\u4f4d\u4e0e\u7cfb\u7edf\u5168\u666f\u300b\u4ee5\u5efa\u7acb\u6574\u4f53\u8ba4\u77e5\u6846\u67b6 &#x1f449;\u5199\u535a\u5ba2\u7684\u670b\u53cb\u53ef\u4ee5\u770b\u770b\u8fd9\u4e2a&amp;#xf","og_url":"https:\/\/www.wsisp.com\/helps\/90019.html","og_site_name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","article_published_time":"2026-08-04T06:57:23+00:00","author":"admin","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"admin","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"84 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.wsisp.com\/helps\/90019.html","url":"https:\/\/www.wsisp.com\/helps\/90019.html","name":"Hermes Agent Gateway\u7edf\u4e00\u63a7\u5236\u9762\u67b6\u6784\u6df1\u5ea6\u89e3\u6790 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","isPartOf":{"@id":"https:\/\/www.wsisp.com\/helps\/#website"},"datePublished":"2026-08-04T06:57:23+00:00","dateModified":"2026-08-04T06:57:23+00:00","author":{"@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41"},"breadcrumb":{"@id":"https:\/\/www.wsisp.com\/helps\/90019.html#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.wsisp.com\/helps\/90019.html"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.wsisp.com\/helps\/90019.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.wsisp.com\/helps"},{"@type":"ListItem","position":2,"name":"Hermes Agent Gateway\u7edf\u4e00\u63a7\u5236\u9762\u67b6\u6784\u6df1\u5ea6\u89e3\u6790"}]},{"@type":"WebSite","@id":"https:\/\/www.wsisp.com\/helps\/#website","url":"https:\/\/www.wsisp.com\/helps\/","name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","description":"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41","name":"admin","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/","url":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","contentUrl":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","caption":"admin"},"sameAs":["http:\/\/wp.wsisp.com"],"url":"https:\/\/www.wsisp.com\/helps\/author\/admin"}]}},"_links":{"self":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/90019","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/comments?post=90019"}],"version-history":[{"count":0,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/90019\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media?parent=90019"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/categories?post=90019"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/tags?post=90019"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/topic?post=90019"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}