{"id":1825,"date":"2026-09-22T15:38:19","date_gmt":"2026-09-22T07:38:19","guid":{"rendered":"https:\/\/www.liujh168.com\/index.php\/2026\/09\/22\/20260922-004\/"},"modified":"2026-09-22T15:38:19","modified_gmt":"2026-09-22T07:38:19","slug":"20260922-004","status":"publish","type":"post","link":"https:\/\/www.liujh168.com\/index.php\/2026\/09\/22\/20260922-004\/","title":{"rendered":"Agent\u5b89\u5168\u4e09\u5c42\u9632\u5fa1"},"content":{"rendered":"<h1 id=\"agent-ast-human-in-the-loop\">\u8ba9 Agent \u5b89\u5168\u6267\u884c\u4ee3\u7801\uff1a\u4ece AST \u767d\u540d\u5355\u5230 Human-in-the-loop \u7684\u4e09\u5c42\u9632\u5fa1<\/h1>\n<blockquote>\n<p>\u4f5c\u8005\uff1aAgent Dev \u5b9e\u8df5\u7b14\u8bb0 | \u53d1\u5e03\u65e5\u671f\uff1a2026-09-21 | \u6807\u7b7e\uff1aAgent, \u5b89\u5168, AST, Human-in-the-loop, Tool Policy<\/p>\n<p><!--more--><\/p>\n<\/blockquote>\n<hr \/>\n<h2 id=\"_1\">\u5f15\u5b50<\/h2>\n<p>\u6211\u89c1\u8fc7\u6709\u4eba\u8dd1 Agent \u65f6\u8bf4\uff1a&#8221;\u6ca1\u4e8b\uff0c\u5927\u4e0d\u4e86\u628a <code>run_terminal<\/code> \u5de5\u5177\u4ece tool_map \u91cc\u5220\u6389\u5c31\u5b89\u5168\u4e86\u3002&#8221;<\/p>\n<p>\u542c\u8d77\u6765\u5f88\u5408\u7406\u5bf9\u5427\uff1f\u5de5\u5177\u6ca1\u6ce8\u518c\uff0cLLM \u60f3\u8c03\u4e5f\u8c03\u4e0d\u5230\u3002<\/p>\n<p>\u4f46\u4f60\u6709\u6ca1\u6709\u60f3\u8fc7\uff0cLLM \u5230\u5e95\u4f1a\u751f\u6210\u4ec0\u4e48\uff1f<\/p>\n<p>\u6709\u4e00\u5929\u6211\u8ba9 qwen3.5-9b \u8dd1\u4e86\u4e00\u4e2a demo\uff0c\u7528\u6237\u8f93\u5165\u662f&#8221;\u5e2e\u6211\u6e05\u7406\u4e00\u4e0b\u9879\u76ee\u6839\u76ee\u5f55\u7684\u4e34\u65f6\u6587\u4ef6&#8221;\u3002\u6a21\u578b\u7b2c\u4e00\u6b21\u8c03 <code>file_read<\/code> \u8bfb\u4e86\u6839\u76ee\u5f55\u5217\u8868\uff0c\u7b2c\u4e8c\u6b21\u8c03 <code>run_terminal<\/code> \u65f6\u751f\u6210\u7684\u547d\u4ee4\u662f\uff1a<\/p>\n<div class=\"highlight\">\n<pre><span><\/span><code><span class=\"nb\">Remove-Item<\/span> <span class=\"n\">-Path<\/span> <span class=\"s2\">&quot;_test_chart.png&quot;<\/span><span class=\"p\">,<\/span><span class=\"s2\">&quot;*.tmp&quot;<\/span><span class=\"p\">,<\/span><span class=\"s2\">&quot;*.log&quot;<\/span> <span class=\"n\">-Force<\/span> <span class=\"n\">-ErrorAction<\/span> <span class=\"n\">SilentlyContinue<\/span>\n<\/code><\/pre>\n<\/div>\n<p>\u770b\u8d77\u6765\u5f88\u5408\u7406\u5bf9\u4e0d\u5bf9\uff1f\u4f46\u5982\u679c\u7528\u6237\u8f93\u5165\u7684\u662f&#8221;\u5e2e\u6211\u6e05\u7406\u4e00\u4e0b\u7535\u8111\u4e0a\u4e0d\u9700\u8981\u7684\u6587\u4ef6&#8221;\uff0c\u6a21\u578b<strong>\u53ef\u80fd<\/strong>\u4f1a\u751f\u6210\uff1a<\/p>\n<div class=\"highlight\">\n<pre><span><\/span><code><span class=\"nb\">Remove-Item<\/span> <span class=\"n\">-Path<\/span> <span class=\"s2\">&quot;C:\\Users\\*\\Documents\\*&quot;<\/span> <span class=\"n\">-Recurse<\/span> <span class=\"n\">-Force<\/span>\n<\/code><\/pre>\n<\/div>\n<p>LLM \u4e0d\u662f\u6076\u610f\u7684\u3002\u4f46\u5b83\u4e5f\u4e0d\u662f\u5b89\u5168\u4e13\u5bb6\u3002\u5b83\u4e0d\u77e5\u9053 <code>Remove-Item -Recurse -Force<\/code> \u4f1a\u5220\u4ec0\u4e48\uff0c\u5b83\u4e5f\u4e0d\u77e5\u9053 C:\\Users*\\Documents* \u91cc\u9762\u6709\u4ec0\u4e48\u3002\u5b83\u53ea\u662f\u5728\u6982\u7387\u4e0a\u751f\u6210\u4e86&#8221;\u6e05\u7406\u6587\u4ef6&#8221;\u8fd9\u53e5\u8bdd\u6700\u53ef\u80fd\u5bf9\u5e94\u7684\u547d\u4ee4\u3002<\/p>\n<p>\u6240\u4ee5<strong>\u5b89\u5168\u4e0d\u80fd\u9760&#8221;LLM \u4f1a\u81ea\u89c9&#8221;<\/strong>\u3002\u6211\u4eec\u9700\u8981<strong>\u7eb5\u6df1\u9632\u5fa1<\/strong>\u2014\u2014\u4ece\u786c\u5230\u8f6f\u3001\u4ece\u4ee3\u7801\u5230\u7528\u6237\uff0c\u5c42\u5c42\u515c\u4f4f\u3002<\/p>\n<hr \/>\n<h2 id=\"_2\">\u4e00\u3001\u4e09\u5c42\u9632\u5fa1\u67b6\u6784\u603b\u89c8<\/h2>\n<p>\u6211\u4eec\u7684\u5b89\u5168\u4f53\u7cfb\u5206\u4e09\u5c42\uff0c\u4ece\u5916\u5230\u5185\u3001\u4ece&#8221;\u4ee3\u7801\u6267\u884c\u4e0d\u5230&#8221;\u5230&#8221;\u8ba9 LLM \u81ea\u5df1\u5224\u65ad&#8221;\uff1a<\/p>\n<div class=\"highlight\">\n<pre><span><\/span><code>\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\n\u2502 \u7b2c\u4e09\u5c42\uff1a\u8ba9 LLM \u81ea\u5df1\u5224\u65ad                                              \u2502\n\u2502 human_confirm \u5de5\u5177\uff08\u6ce8\u518c\u4e3a Function Calling \u5de5\u5177\uff09                   \u2502\n\u2502 \u2192 &quot;\u654f\u611f\u64cd\u4f5c\u524d\u8bf7\u8c03\u8fd9\u4e2a\u5de5\u5177&quot; \u2192 Agent \u53ef\u4ee5\u4e3b\u52a8\u6682\u505c\u7b49\u7528\u6237\u786e\u8ba4              \u2502\n\u2502                                                                     \u2502\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  \u2502\n\u2502 \u7b2c\u4e8c\u5c42\uff1a\u8f6f\u62e6\u622a                                                       \u2502\n\u2502 ToolPolicy \u56db\u7ea7\u98ce\u9669\u5206\u7c7b + ToolExecutor                              \u2502\n\u2502 classify \u2192 \u5224\u5b9a \u2192 allow\/confirm \u2192 \u6267\u884c\/\u62e6\u622a                           \u2502\n\u2502                                                                     \u2502\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  \u2502\n\u2502 \u7b2c\u4e00\u5c42\uff1a\u786c\u62e6\u622a                                                       \u2502\n\u2502 AST \u767d\u540d\u5355 + SQL mode=ro + PowerShell \u5173\u952e\u8bcd\u9ed1\u540d\u5355                    \u2502\n\u2502 \u2192 \u5728\u51fd\u6570\u5185\u90e8\uff0c\u5371\u9669\u8f93\u5165\u88ab\u62e6\u622a\uff0c\u6267\u884c\u4e0d\u5230 OS \u5c42                          \u2502\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\n<\/code><\/pre>\n<\/div>\n<hr \/>\n<h2 id=\"_3\">\u4e8c\u3001\u7b2c\u4e00\u5c42\uff1a\u786c\u62e6\u622a \u2014 \u6839\u672c\u6267\u884c\u4e0d\u5230\u5371\u9669\u8def\u5f84<\/h2>\n<p>\u786c\u62e6\u622a\u662f&#8221;\u628a\u5371\u9669\u6321\u5728\u51fd\u6570\u95e8\u53e3&#8221;\u2014\u2014\u4e0d\u7ba1\u8c01\u8c03\u8fd9\u4e2a\u51fd\u6570\uff08LLM \u8c03\u7684\u3001\u6d4b\u8bd5\u4ee3\u7801\u8c03\u7684\u3001\u672a\u6765\u67d0\u4e2a\u65b0 Agent \u8c03\u7684\uff09\uff0c\u53ea\u8981\u8f93\u5165\u662f\u5371\u9669\u7684\uff0c\u51fd\u6570\u76f4\u63a5\u8fd4\u56de\u9519\u8bef\uff0c\u6c38\u8fdc\u6267\u884c\u4e0d\u5230\u771f\u6b63\u7684\u5371\u9669\u4ee3\u7801\u3002<\/p>\n<h3 id=\"21-calculatorast\">2.1 Calculator\uff1aAST \u767d\u540d\u5355<\/h3>\n<p><code>calculator<\/code> \u5de5\u5177\u7684\u95ee\u9898\u662f&#8221;\u8ba9 LLM \u5199\u4e00\u4e2a\u6570\u5b66\u8868\u8fbe\u5f0f\u7136\u540e eval \u5b83&#8221;\u3002\u4f46\u5982\u679c\u8868\u8fbe\u5f0f\u662f <code>__import__('os').listdir()<\/code> \u5462\uff1f<code>eval<\/code> \u4f1a\u771f\u7684\u6267\u884c\u3002<\/p>\n<p>\u6211\u4eec\u7684\u89e3\u6cd5\u662f<strong>\u6839\u672c\u4e0d\u8ba9 <code>eval<\/code> \u89c1\u5230\u4efb\u4f55\u975e\u6570\u5b66\u8282\u70b9<\/strong>\uff1a<\/p>\n<div class=\"highlight\">\n<pre><span><\/span><code><span class=\"c1\"># tools\/demo.py \u2014 \u7b80\u5316\u7248\uff08\u771f\u5b9e\u4ee3\u7801\u5728\u9879\u76ee\u91cc\uff09<\/span>\n<span class=\"kn\">import<\/span><span class=\"w\"> <\/span><span class=\"nn\">ast<\/span>\n\n<span class=\"n\">_ALLOWED_OPS<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span><span class=\"n\">ast<\/span><span class=\"o\">.<\/span><span class=\"n\">Add<\/span><span class=\"p\">,<\/span> <span class=\"n\">ast<\/span><span class=\"o\">.<\/span><span class=\"n\">Sub<\/span><span class=\"p\">,<\/span> <span class=\"n\">ast<\/span><span class=\"o\">.<\/span><span class=\"n\">Mult<\/span><span class=\"p\">,<\/span> <span class=\"n\">ast<\/span><span class=\"o\">.<\/span><span class=\"n\">Div<\/span><span class=\"p\">,<\/span> <span class=\"n\">ast<\/span><span class=\"o\">.<\/span><span class=\"n\">Pow<\/span><span class=\"p\">,<\/span> <span class=\"n\">ast<\/span><span class=\"o\">.<\/span><span class=\"n\">Mod<\/span><span class=\"p\">,<\/span> <span class=\"n\">ast<\/span><span class=\"o\">.<\/span><span class=\"n\">USub<\/span><span class=\"p\">}<\/span>\n\n<span class=\"k\">def<\/span><span class=\"w\"> <\/span><span class=\"nf\">calculator<\/span><span class=\"p\">(<\/span><span class=\"n\">expression<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">str<\/span><span class=\"p\">:<\/span>\n    <span class=\"k\">try<\/span><span class=\"p\">:<\/span>\n        <span class=\"n\">tree<\/span> <span class=\"o\">=<\/span> <span class=\"n\">ast<\/span><span class=\"o\">.<\/span><span class=\"n\">parse<\/span><span class=\"p\">(<\/span><span class=\"n\">expression<\/span><span class=\"p\">,<\/span> <span class=\"n\">mode<\/span><span class=\"o\">=<\/span><span class=\"s2\">&quot;eval&quot;<\/span><span class=\"p\">)<\/span>\n        <span class=\"c1\"># \u9012\u5f52\u6821\u9a8c\u6bcf\u4e00\u4e2a\u8282\u70b9<\/span>\n        <span class=\"n\">_safe_eval<\/span><span class=\"p\">(<\/span><span class=\"n\">tree<\/span><span class=\"o\">.<\/span><span class=\"n\">body<\/span><span class=\"p\">)<\/span>   <span class=\"c1\"># \u2190 \u5728\u8fd9\u91cc\u4f1a\u62d2\u7edd Call\/Name\/Attribute \u7b49<\/span>\n        <span class=\"k\">return<\/span> <span class=\"s2\">&quot;OK&quot;<\/span>\n    <span class=\"k\">except<\/span> <span class=\"ne\">Exception<\/span> <span class=\"k\">as<\/span> <span class=\"n\">exc<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">return<\/span> <span class=\"sa\">f<\/span><span class=\"s2\">&quot;\u8ba1\u7b97\u5931\u8d25: <\/span><span class=\"si\">{<\/span><span class=\"n\">exc<\/span><span class=\"si\">}<\/span><span class=\"s2\">&quot;<\/span>\n\n<span class=\"k\">def<\/span><span class=\"w\"> <\/span><span class=\"nf\">_safe_eval<\/span><span class=\"p\">(<\/span><span class=\"n\">node<\/span><span class=\"p\">):<\/span>\n    <span class=\"k\">if<\/span> <span class=\"nb\">isinstance<\/span><span class=\"p\">(<\/span><span class=\"n\">node<\/span><span class=\"p\">,<\/span> <span class=\"n\">ast<\/span><span class=\"o\">.<\/span><span class=\"n\">BinOp<\/span><span class=\"p\">):<\/span>\n        <span class=\"k\">if<\/span> <span class=\"nb\">type<\/span><span class=\"p\">(<\/span><span class=\"n\">node<\/span><span class=\"o\">.<\/span><span class=\"n\">op<\/span><span class=\"p\">)<\/span> <span class=\"ow\">not<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">_ALLOWED_OPS<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">raise<\/span> <span class=\"ne\">ValueError<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"s2\">&quot;\u4e0d\u652f\u6301\u7684\u8fd0\u7b97\u7b26: <\/span><span class=\"si\">{<\/span><span class=\"nb\">type<\/span><span class=\"p\">(<\/span><span class=\"n\">node<\/span><span class=\"o\">.<\/span><span class=\"n\">op<\/span><span class=\"p\">)<\/span><span class=\"o\">.<\/span><span class=\"vm\">__name__<\/span><span class=\"si\">}<\/span><span class=\"s2\">&quot;<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">_safe_eval<\/span><span class=\"p\">(<\/span><span class=\"n\">node<\/span><span class=\"o\">.<\/span><span class=\"n\">left<\/span><span class=\"p\">),<\/span> <span class=\"n\">_safe_eval<\/span><span class=\"p\">(<\/span><span class=\"n\">node<\/span><span class=\"o\">.<\/span><span class=\"n\">right<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">if<\/span> <span class=\"nb\">isinstance<\/span><span class=\"p\">(<\/span><span class=\"n\">node<\/span><span class=\"p\">,<\/span> <span class=\"n\">ast<\/span><span class=\"o\">.<\/span><span class=\"n\">Constant<\/span><span class=\"p\">)<\/span> <span class=\"ow\">and<\/span> <span class=\"nb\">isinstance<\/span><span class=\"p\">(<\/span><span class=\"n\">node<\/span><span class=\"o\">.<\/span><span class=\"n\">value<\/span><span class=\"p\">,<\/span> <span class=\"p\">(<\/span><span class=\"nb\">int<\/span><span class=\"p\">,<\/span> <span class=\"nb\">float<\/span><span class=\"p\">)):<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">node<\/span><span class=\"o\">.<\/span><span class=\"n\">value<\/span>\n    <span class=\"c1\"># \u2191 \u53ea\u5141\u8bb8 BinOp\uff08\u56db\u5219\u8fd0\u7b97\uff09\u548c Constant\uff08\u6570\u5b57\u5e38\u91cf\uff09<\/span>\n    <span class=\"c1\"># Call \/ Name \/ Attribute \/ Subscript \/ Lambda \u2014 \u4e00\u5f8b\u62d2\u7edd<\/span>\n    <span class=\"k\">raise<\/span> <span class=\"ne\">ValueError<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"s2\">&quot;\u4e0d\u652f\u6301\u7684\u8868\u8fbe\u5f0f\u5143\u7d20: <\/span><span class=\"si\">{<\/span><span class=\"nb\">type<\/span><span class=\"p\">(<\/span><span class=\"n\">node<\/span><span class=\"p\">)<\/span><span class=\"o\">.<\/span><span class=\"vm\">__name__<\/span><span class=\"si\">}<\/span><span class=\"s2\">&quot;<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre>\n<\/div>\n<p><code>eval(\"__import__('os').listdir()\")<\/code> \u7684 AST \u4f1a\u6709\u4e00\u4e2a <code>Call<\/code> \u8282\u70b9 \u2192 <code>_safe_eval<\/code> \u9047\u5230 <code>Call<\/code> \u2192 \u76f4\u63a5 raise \u2192 \u9519\u8bef\u8fd4\u56de \u2192 <strong>LLM \u62ff\u4e0d\u5230\u6267\u884c\u673a\u4f1a<\/strong>\u3002<\/p>\n<h3 id=\"22-sql\">2.2 SQL\uff1a\u6570\u636e\u5e93\u5c42\u7269\u7406\u53ea\u8bfb<\/h3>\n<div class=\"highlight\">\n<pre><span><\/span><code><span class=\"c1\"># tools\/sql.py \u2014 SQLite URI \u53c2\u6570 + PRAGMA \u53cc\u91cd\u53ea\u8bfb<\/span>\n<span class=\"n\">uri<\/span> <span class=\"o\">=<\/span> <span class=\"n\">abs_path<\/span><span class=\"o\">.<\/span><span class=\"n\">as_uri<\/span><span class=\"p\">()<\/span> <span class=\"o\">+<\/span> <span class=\"s2\">&quot;?mode=ro&quot;<\/span>    <span class=\"c1\"># \u2190 OS \u6587\u4ef6\u7ea7\u53ea\u8bfb\uff1a\u65e0\u6cd5\u5199\u6587\u4ef6<\/span>\n<span class=\"n\">conn<\/span> <span class=\"o\">=<\/span> <span class=\"n\">sqlite3<\/span><span class=\"o\">.<\/span><span class=\"n\">connect<\/span><span class=\"p\">(<\/span><span class=\"n\">uri<\/span><span class=\"p\">,<\/span> <span class=\"n\">uri<\/span><span class=\"o\">=<\/span><span class=\"kc\">True<\/span><span class=\"p\">)<\/span>\n<span class=\"n\">conn<\/span><span class=\"o\">.<\/span><span class=\"n\">execute<\/span><span class=\"p\">(<\/span><span class=\"s2\">&quot;PRAGMA query_only=ON&quot;<\/span><span class=\"p\">)<\/span>   <span class=\"c1\"># \u2190 SQLite \u5f15\u64ce\u7ea7\u53ea\u8bfb\uff1a\u65e0\u6cd5\u6267\u884c\u5199\u64cd\u4f5c<\/span>\n<\/code><\/pre>\n<\/div>\n<p>\u4e24\u5c42\u4fdd\u62a4\uff1a<br \/>\n&#8211; URI <code>mode=ro<\/code> \u8ba9 SQLite \u6839\u672c\u6253\u4e0d\u5f00\u6587\u4ef6\u7684\u5199\u5165\u53e5\u67c4 \u2192 OS \u5c42\u62d2\u7edd<br \/>\n&#8211; <code>PRAGMA query_only=ON<\/code> \u8ba9 SQLite \u5f15\u64ce\u62d2\u7edd\u6240\u6709\u5199\u64cd\u4f5c \u2192 \u5f15\u64ce\u5c42\u62d2\u7edd<\/p>\n<p><code>DROP TABLE users<\/code> \u4f1a\u5728 SQL \u6267\u884c\u65f6\u88ab\u5f15\u64ce\u62d2\u7edd\uff0c\u6839\u672c\u4e0d\u4f1a\u771f\u6b63\u5220\u6570\u636e\u3002<\/p>\n<h3 id=\"23-powershell\">2.3 PowerShell \u5173\u952e\u8bcd\u9ed1\u540d\u5355<\/h3>\n<div class=\"highlight\">\n<pre><span><\/span><code><span class=\"c1\"># tools\/system.py \u2014 \u7b80\u5316\u7248<\/span>\n<span class=\"n\">_DANGEROUS_CMD_PATTERNS<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span>\n    <span class=\"s2\">&quot;rm -rf \/&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s2\">&quot;Remove-Item -Recurse -Force&quot;<\/span><span class=\"p\">,<\/span>\n    <span class=\"s2\">&quot;Stop-Computer&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s2\">&quot;Restart-Computer&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s2\">&quot;Format-Volume&quot;<\/span><span class=\"p\">,<\/span>\n    <span class=\"s2\">&quot;Set-Content&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s2\">&quot;Invoke-WebRequest -OutFile&quot;<\/span><span class=\"p\">,<\/span>\n    <span class=\"c1\"># ... \u7ea6 40 \u6761<\/span>\n<span class=\"p\">]<\/span>\n\n<span class=\"k\">def<\/span><span class=\"w\"> <\/span><span class=\"nf\">run_terminal<\/span><span class=\"p\">(<\/span><span class=\"n\">command<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">str<\/span><span class=\"p\">:<\/span>\n    <span class=\"c1\"># \u786c\u62e6\u622a\u7b2c\u4e00\u6b65\uff1a\u5173\u952e\u8bcd\u5339\u914d<\/span>\n    <span class=\"k\">for<\/span> <span class=\"n\">pattern<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">_DANGEROUS_CMD_PATTERNS<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">re<\/span><span class=\"o\">.<\/span><span class=\"n\">search<\/span><span class=\"p\">(<\/span><span class=\"n\">pattern<\/span><span class=\"p\">,<\/span> <span class=\"n\">command<\/span><span class=\"p\">,<\/span> <span class=\"n\">re<\/span><span class=\"o\">.<\/span><span class=\"n\">IGNORECASE<\/span><span class=\"p\">):<\/span>\n            <span class=\"k\">return<\/span> <span class=\"sa\">f<\/span><span class=\"s2\">&quot;\u5b89\u5168\u62e6\u622a\uff1a\u547d\u4ee4\u5305\u542b\u5371\u9669\u5173\u952e\u8bcd &#39;<\/span><span class=\"si\">{<\/span><span class=\"n\">pattern<\/span><span class=\"si\">}<\/span><span class=\"s2\">&#39;&quot;<\/span>\n    <span class=\"c1\"># \u901a\u8fc7\u540e\u624d\u771f\u7684 subprocess.run(command)<\/span>\n    <span class=\"o\">...<\/span>\n<\/code><\/pre>\n<\/div>\n<p>\u5173\u952e\u8bcd\u9ed1\u540d\u5355\u4e0d\u662f\u5b8c\u7f8e\u7684\uff08\u53ef\u4ee5\u88ab\u7ed5\u8fc7\uff09\uff0c\u4f46\u5b83\u662f<strong>\u7b2c\u4e00\u9053\u5173<\/strong>\u2014\u2014\u7edd\u5927\u591a\u6570\u5e38\u89c1\u5371\u9669\u547d\u4ee4\u4f1a\u5728\u8fd9\u91cc\u88ab\u62e6\u4e0b\u3002<\/p>\n<hr \/>\n<h2 id=\"_4\">\u4e09\u3001\u7b2c\u4e8c\u5c42\uff1a\u8f6f\u62e6\u622a \u2014 \u8c01\u53ef\u4ee5\u8c03\u4ec0\u4e48<\/h2>\n<p>\u786c\u62e6\u622a\u662f\u51fd\u6570\u5185\u90e8\u7684\u9632\u7ebf\u3002\u4f46\u5728 Agent \u4f53\u7cfb\u91cc\uff0c\u6211\u4eec\u8fd8\u9700\u8981<strong>\u51fd\u6570\u5916\u9762<\/strong>\u7684\u9632\u7ebf\u2014\u2014\u51b3\u5b9a&#8221;\u5f53\u524d\u8fd9\u4e2a Agent \u5b9e\u4f8b\u80fd\u4e0d\u80fd\u7528 run_terminal&#8221;\u3002<\/p>\n<h3 id=\"31-toolpolicy\">3.1 ToolPolicy\uff1a\u56db\u7ea7\u98ce\u9669\u5206\u7c7b<\/h3>\n<div class=\"highlight\">\n<pre><span><\/span><code><span class=\"c1\"># tooling.py \u2014 \u53ea\u9760\u5de5\u5177\u540d\u5224\u65ad\u98ce\u9669\u7b49\u7ea7<\/span>\n<span class=\"n\">EXECUTE_TOOLS<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">frozenset<\/span><span class=\"p\">({<\/span><span class=\"s2\">&quot;run_code&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s2\">&quot;run_terminal&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s2\">&quot;demo_code_run&quot;<\/span><span class=\"p\">})<\/span>\n<span class=\"n\">WRITE_TOOLS<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">frozenset<\/span><span class=\"p\">({<\/span><span class=\"s2\">&quot;file_write&quot;<\/span><span class=\"p\">})<\/span>\n\n<span class=\"k\">class<\/span><span class=\"w\"> <\/span><span class=\"nc\">ToolPolicy<\/span><span class=\"p\">:<\/span>\n    <span class=\"k\">def<\/span><span class=\"w\"> <\/span><span class=\"nf\">classify<\/span><span class=\"p\">(<\/span><span class=\"bp\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">name<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">RiskKind<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">name<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">EXECUTE_TOOLS<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">return<\/span> <span class=\"s2\">&quot;execute&quot;<\/span>       <span class=\"c1\"># \u6267\u884c\u7c7b\uff08subprocess \/ eval\uff09<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">name<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">WRITE_TOOLS<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">return<\/span> <span class=\"s2\">&quot;write&quot;<\/span>         <span class=\"c1\"># \u5199\u5165\u7c7b\uff08\u6587\u4ef6\u5199\u5165\uff09<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">name<\/span><span class=\"o\">.<\/span><span class=\"n\">startswith<\/span><span class=\"p\">(<\/span><span class=\"s2\">&quot;mcp_&quot;<\/span><span class=\"p\">):<\/span>\n            <span class=\"k\">return<\/span> <span class=\"s2\">&quot;mcp&quot;<\/span>           <span class=\"c1\"># MCP \u8fdc\u7aef\u5de5\u5177<\/span>\n        <span class=\"k\">return<\/span> <span class=\"s2\">&quot;read&quot;<\/span>              <span class=\"c1\"># \u9ed8\u8ba4\uff1a\u53ea\u8bfb<\/span>\n\n    <span class=\"n\">allow_write<\/span><span class=\"p\">:<\/span> <span class=\"nb\">bool<\/span> <span class=\"o\">=<\/span> <span class=\"kc\">True<\/span>\n    <span class=\"n\">allow_execute<\/span><span class=\"p\">:<\/span> <span class=\"nb\">bool<\/span> <span class=\"o\">=<\/span> <span class=\"kc\">False<\/span>    <span class=\"c1\"># \u2190 \u9ed8\u8ba4\u7981\u6b62\u6267\u884c\u7c7b\u5de5\u5177<\/span>\n    <span class=\"n\">allow_mcp<\/span><span class=\"p\">:<\/span> <span class=\"nb\">bool<\/span> <span class=\"o\">=<\/span> <span class=\"kc\">True<\/span>\n    <span class=\"n\">confirm_write<\/span><span class=\"p\">:<\/span> <span class=\"nb\">bool<\/span> <span class=\"o\">=<\/span> <span class=\"kc\">False<\/span>\n    <span class=\"n\">confirm_execute<\/span><span class=\"p\">:<\/span> <span class=\"nb\">bool<\/span> <span class=\"o\">=<\/span> <span class=\"kc\">True<\/span>   <span class=\"c1\"># \u2190 \u5982\u679c\u5141\u8bb8\uff0c\u6bcf\u6b21\u9700\u8981\u786e\u8ba4<\/span>\n    <span class=\"n\">confirm_mcp<\/span><span class=\"p\">:<\/span> <span class=\"nb\">bool<\/span> <span class=\"o\">=<\/span> <span class=\"kc\">True<\/span>\n<\/code><\/pre>\n<\/div>\n<p>\u56db\u7ea7\u5206\u7c7b + 6 \u4e2a\u5e03\u5c14\u5f00\u5173\uff0c\u4e00\u884c\u914d\u7f6e\u5c31\u80fd\u5207\u6362\u6574\u5957\u5b89\u5168\u7b56\u7565\u3002<\/p>\n<h3 id=\"32-surface\">3.2 \u4e0d\u540c surface \u53ef\u4ee5\u6709\u4e0d\u540c\u7b56\u7565<\/h3>\n<div class=\"highlight\">\n<pre><span><\/span><code><span class=\"c1\"># CLI \u7aef\uff1a\u5141\u8bb8 execute\uff0c\u4f46\u6bcf\u6b21\u9700\u8981\u786e\u8ba4<\/span>\n<span class=\"n\">cli_executor<\/span> <span class=\"o\">=<\/span> <span class=\"n\">ToolExecutor<\/span><span class=\"p\">(<\/span>\n    <span class=\"n\">tool_map<\/span><span class=\"p\">,<\/span>\n    <span class=\"n\">policy<\/span><span class=\"o\">=<\/span><span class=\"n\">ToolPolicy<\/span><span class=\"p\">(<\/span>\n        <span class=\"n\">allow_write<\/span><span class=\"o\">=<\/span><span class=\"kc\">True<\/span><span class=\"p\">,<\/span>\n        <span class=\"n\">allow_execute<\/span><span class=\"o\">=<\/span><span class=\"kc\">True<\/span><span class=\"p\">,<\/span>        <span class=\"c1\"># CLI \u7528\u6237\u5728\u81ea\u5df1\u7535\u8111\u4e0a<\/span>\n        <span class=\"n\">confirm_execute<\/span><span class=\"o\">=<\/span><span class=\"kc\">True<\/span><span class=\"p\">,<\/span>      <span class=\"c1\"># \u4f46\u6bcf\u6b21\u90fd\u5f39\u786e\u8ba4<\/span>\n    <span class=\"p\">),<\/span>\n    <span class=\"n\">confirm<\/span><span class=\"o\">=<\/span><span class=\"k\">lambda<\/span> <span class=\"n\">name<\/span><span class=\"p\">,<\/span> <span class=\"n\">risk<\/span><span class=\"p\">,<\/span> <span class=\"n\">args<\/span><span class=\"p\">:<\/span> <span class=\"nb\">input<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"s2\">&quot;\u26a0\ufe0f \u5373\u5c06\u6267\u884c <\/span><span class=\"si\">{<\/span><span class=\"n\">name<\/span><span class=\"si\">}<\/span><span class=\"s2\">\uff0c\u786e\u8ba4\uff1f[y\/N] &quot;<\/span><span class=\"p\">)<\/span><span class=\"o\">.<\/span><span class=\"n\">lower<\/span><span class=\"p\">()<\/span> <span class=\"o\">==<\/span> <span class=\"s2\">&quot;y&quot;<\/span><span class=\"p\">,<\/span>\n<span class=\"p\">)<\/span>\n\n<span class=\"c1\"># Web UI \u7aef\uff1a\u5b8c\u5168\u7981\u6b62 execute<\/span>\n<span class=\"n\">web_executor<\/span> <span class=\"o\">=<\/span> <span class=\"n\">ToolExecutor<\/span><span class=\"p\">(<\/span>\n    <span class=\"n\">tool_map<\/span><span class=\"p\">,<\/span>\n    <span class=\"n\">policy<\/span><span class=\"o\">=<\/span><span class=\"n\">ToolPolicy<\/span><span class=\"p\">(<\/span>\n        <span class=\"n\">allow_write<\/span><span class=\"o\">=<\/span><span class=\"kc\">True<\/span><span class=\"p\">,<\/span>\n        <span class=\"n\">allow_execute<\/span><span class=\"o\">=<\/span><span class=\"kc\">False<\/span><span class=\"p\">,<\/span>       <span class=\"c1\"># Web \u7aef\u7981\u6b62<\/span>\n    <span class=\"p\">),<\/span>\n<span class=\"p\">)<\/span>\n<\/code><\/pre>\n<\/div>\n<p>\u6ce8\u610f\uff1a<strong>\u540c\u4e00\u4e2a tool_map<\/strong>\uff0821 \u4e2a\u5de5\u5177\uff09\uff0c\u4e24\u4e2a surface \u5404\u81ea\u6784\u9020\u4e0d\u540c\u7684 ToolExecutor\u3002CLI \u4e0a <code>run_terminal<\/code> \u53ef\u7528\u4f46\u8981\u786e\u8ba4\uff0cWeb UI \u4e0a\u76f4\u63a5\u88ab\u62d2\u3002<\/p>\n<h3 id=\"33-allow_unsafe\">3.3 \u81ea\u52a8\u6ce8\u5165 allow_unsafe<\/h3>\n<div class=\"highlight\">\n<pre><span><\/span><code><span class=\"c1\"># tooling.py ToolExecutor.execute() \u5185\u90e8<\/span>\n<span class=\"n\">params<\/span> <span class=\"o\">=<\/span> <span class=\"n\">inspect<\/span><span class=\"o\">.<\/span><span class=\"n\">signature<\/span><span class=\"p\">(<\/span><span class=\"n\">func<\/span><span class=\"p\">)<\/span><span class=\"o\">.<\/span><span class=\"n\">parameters<\/span>\n<span class=\"k\">if<\/span> <span class=\"n\">risk<\/span> <span class=\"o\">==<\/span> <span class=\"s2\">&quot;execute&quot;<\/span> <span class=\"ow\">and<\/span> <span class=\"s2\">&quot;allow_unsafe&quot;<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">params<\/span><span class=\"p\">:<\/span>\n    <span class=\"n\">kwargs<\/span><span class=\"p\">[<\/span><span class=\"s2\">&quot;allow_unsafe&quot;<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"kc\">True<\/span>\n<\/code><\/pre>\n<\/div>\n<p>\u6211\u4eec\u7684 <code>run_terminal<\/code> \/ <code>run_code<\/code> \u6709\u4e00\u4e2a <code>allow_unsafe=False<\/code> \u53c2\u6570\uff0c\u9ed8\u8ba4\u4e0d\u5141\u8bb8\u3002ToolExecutor \u68c0\u6d4b\u5230\u8fd9\u662f execute \u98ce\u9669\u4e14\u51fd\u6570\u6709 <code>allow_unsafe<\/code> \u53c2\u6570\u65f6\uff0c<strong>\u81ea\u52a8\u6ce8\u5165 <code>allow_unsafe=True<\/code><\/strong>\u2014\u2014\u4f46\u524d\u63d0\u662f\u8fd9\u4e2a surface \u5141\u8bb8 execute\u3002\u8fd9\u662f\u4e2a\u5c0f\u6280\u5de7\uff1a\u8ba9\u5de5\u5177\u51fd\u6570\u7684\u9ed8\u8ba4\u884c\u4e3a\u662f&#8221;\u4e0d\u5b89\u5168&#8221;\uff0c\u53ea\u6709\u5b89\u5168\u7b56\u7565\u653e\u884c\u65f6\u624d\u89e3\u9501\u3002<\/p>\n<hr \/>\n<h2 id=\"llm-human_confirm\">\u56db\u3001\u7b2c\u4e09\u5c42\uff1a\u8ba9 LLM \u81ea\u5df1\u5224\u65ad \u2014 human_confirm<\/h2>\n<p>\u524d\u4e24\u5c42\u90fd\u662f<strong>\u6211\u4eec\u7684\u4ee3\u7801\u5728\u62e6\u622a<\/strong>\u3002\u4f46\u8fd8\u6709\u4e00\u5c42\u662f<strong>\u8ba9 LLM \u4e3b\u52a8\u914d\u5408<\/strong>\u2014\u2014\u6ce8\u518c\u4e00\u4e2a&#8221;\u5411\u7528\u6237\u8bf7\u6c42\u786e\u8ba4&#8221;\u7684\u5de5\u5177\u3002<\/p>\n<h3 id=\"41-human_confirm\">4.1 human_confirm \u662f\u4ec0\u4e48<\/h3>\n<p><code>human_confirm<\/code> \u662f\u4e00\u4e2a <strong>Function Calling \u5de5\u5177<\/strong>\u2014\u2014\u548c calculator\u3001file_read \u5e76\u5217\u7684\u5de5\u5177\u3002LLM \u53ef\u4ee5\u8c03\u5b83\u3002<\/p>\n<div class=\"highlight\">\n<pre><span><\/span><code><span class=\"c1\"># app_core.py \u2014 Tool Schema<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"s2\">&quot;type&quot;<\/span><span class=\"p\">:<\/span> <span class=\"s2\">&quot;function&quot;<\/span><span class=\"p\">,<\/span>\n    <span class=\"s2\">&quot;function&quot;<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\n        <span class=\"s2\">&quot;name&quot;<\/span><span class=\"p\">:<\/span> <span class=\"s2\">&quot;human_confirm&quot;<\/span><span class=\"p\">,<\/span>\n        <span class=\"s2\">&quot;description&quot;<\/span><span class=\"p\">:<\/span> <span class=\"s2\">&quot;Human-in-the-loop \u4eba\u5de5\u786e\u8ba4\u3002\u6267\u884c\u654f\u611f\/\u7834\u574f\u6027\u64cd\u4f5c\u524d\u6682\u505c\u7b49\u5f85\u7528\u6237\u786e\u8ba4...&quot;<\/span><span class=\"p\">,<\/span>\n        <span class=\"s2\">&quot;parameters&quot;<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\n            <span class=\"s2\">&quot;type&quot;<\/span><span class=\"p\">:<\/span> <span class=\"s2\">&quot;object&quot;<\/span><span class=\"p\">,<\/span>\n            <span class=\"s2\">&quot;properties&quot;<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\n                <span class=\"s2\">&quot;action&quot;<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\n                    <span class=\"s2\">&quot;type&quot;<\/span><span class=\"p\">:<\/span> <span class=\"s2\">&quot;string&quot;<\/span><span class=\"p\">,<\/span>\n                    <span class=\"s2\">&quot;description&quot;<\/span><span class=\"p\">:<\/span> <span class=\"s2\">&quot;\u63cf\u8ff0\u5373\u5c06\u6267\u884c\u7684\u64cd\u4f5c&quot;<\/span>\n                <span class=\"p\">}<\/span>\n            <span class=\"p\">},<\/span>\n            <span class=\"s2\">&quot;required&quot;<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span><span class=\"s2\">&quot;action&quot;<\/span><span class=\"p\">],<\/span>\n        <span class=\"p\">},<\/span>\n    <span class=\"p\">},<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n<\/div>\n<p>System Prompt \u91cc\u6709\u6307\u5f15\uff1a<\/p>\n<blockquote>\n<p>\u6267\u884c\u654f\u611f\/\u7834\u574f\u6027\u64cd\u4f5c\u524d\uff08\u5220\u9664\u8986\u76d6\u6587\u4ef6\u3001\u5199\u5165\u91cd\u8981\u6570\u636e\u3001SQL DDL\/DML\u3001\u7ec8\u7aef\u5199\u5165\u547d\u4ee4\uff09\uff0c<strong>\u5fc5\u987b\u5148\u8c03\u7528<\/strong> human_confirm \u8ba9\u7528\u6237\u786e\u8ba4\u3002<\/p>\n<\/blockquote>\n<h3 id=\"42\">4.2 \u89e6\u53d1\u65f6\u673a<\/h3>\n<p>LLM \u5728&#8221;\u60f3\u8c03 run_terminal&#8221;\u4e4b\u524d\uff0c\u5148\u60f3&#8221;\u6211\u8981\u4e0d\u8981\u5148\u95ee\u4e00\u4e0b\u7528\u6237&#8221;\u2014\u2014\u7136\u540e\u8c03 <code>human_confirm(action=\"\u5c06\u6267\u884c rm -rf _temp_dir\/\uff0c\u786e\u8ba4\u6e05\u7406\uff1f\")<\/code>\u3002<\/p>\n<p>CLI \u7aef\u540c\u6b65\u963b\u585e\u7b49\u7528\u6237\u8f93\u5165\uff1a<\/p>\n<div class=\"highlight\">\n<pre><span><\/span><code><span class=\"k\">def<\/span><span class=\"w\"> <\/span><span class=\"nf\">cli_human_confirm<\/span><span class=\"p\">(<\/span><span class=\"n\">action<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">str<\/span><span class=\"p\">:<\/span>\n    <span class=\"n\">resp<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">input<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"s2\">&quot;\ud83e\udd14 <\/span><span class=\"si\">{<\/span><span class=\"n\">action<\/span><span class=\"si\">}<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">\u8bf7\u8f93\u5165 y\/yes \u786e\u8ba4\uff0c\u5176\u4ed6\u4efb\u610f\u952e\u53d6\u6d88: &quot;<\/span><span class=\"p\">)<\/span><span class=\"o\">.<\/span><span class=\"n\">strip<\/span><span class=\"p\">()<\/span><span class=\"o\">.<\/span><span class=\"n\">lower<\/span><span class=\"p\">()<\/span>\n    <span class=\"k\">return<\/span> <span class=\"s2\">&quot;\u7528\u6237\u5df2\u6279\u51c6&quot;<\/span> <span class=\"k\">if<\/span> <span class=\"n\">resp<\/span> <span class=\"ow\">in<\/span> <span class=\"p\">(<\/span><span class=\"s2\">&quot;y&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s2\">&quot;yes&quot;<\/span><span class=\"p\">)<\/span> <span class=\"k\">else<\/span> <span class=\"s2\">&quot;\u7528\u6237\u53d6\u6d88&quot;<\/span>\n<\/code><\/pre>\n<\/div>\n<p>Web UI \u7aef\u66f4\u590d\u6742\u2014\u2014\u9700\u8981\u7528 Gradio queue + \u4e8b\u4ef6\u56de\u8c03\u5b9e\u73b0\u6682\u505c\u7b49\u5f85\uff1a<\/p>\n<div class=\"highlight\">\n<pre><span><\/span><code><span class=\"c1\"># Web \u7aef\uff1a\u628a human_confirm \u7684\u6267\u884c\u6743\u4ea4\u7ed9 Gradio \u4e8b\u4ef6\u5faa\u73af<\/span>\n<span class=\"k\">def<\/span><span class=\"w\"> <\/span><span class=\"nf\">web_human_confirm<\/span><span class=\"p\">(<\/span><span class=\"n\">action<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">str<\/span><span class=\"p\">:<\/span>\n    <span class=\"c1\"># \u89e6\u53d1\u524d\u7aef\u5f39\u786e\u8ba4\u6846\uff0c\u6682\u505c Agent \u6267\u884c\u6d41<\/span>\n    <span class=\"c1\"># \u7528\u6237\u70b9\u51fb\u540e\u7ed3\u679c\u901a\u8fc7 thread-local \u4f20\u56de<\/span>\n    <span class=\"o\">...<\/span>\n<\/code><\/pre>\n<\/div>\n<h3 id=\"43\">4.3 \u4e09\u5c42\u9632\u5fa1\u5982\u4f55\u4e32\u8054<\/h3>\n<div class=\"highlight\">\n<pre><span><\/span><code>\u7528\u6237\u8bf4&quot;\u6e05\u7406\u4e00\u4e0b\u4e34\u65f6\u6587\u4ef6&quot;\n        \u2193\nLLM \u60f3\u8c03 run_terminal \u2192 human_confirm(action=&quot;\u6267\u884c Remove-Item -Path _temp -Force&quot;)\n        \u2193\n\u7b2c\u4e09\u5c42\uff1ahuman_confirm \u5f39\u786e\u8ba4 \u2192 \u7528\u6237\u70b9&quot;\u62d2\u7edd&quot;\n        \u2193\nLLM \u6536\u5230\u7ed3\u679c &quot;\u7528\u6237\u53d6\u6d88&quot; \u2192 \u653e\u5f03\u6267\u884c \u2192 \u56de\u590d&quot;\u597d\u7684\uff0c\u6211\u6ca1\u6267\u884c\u4efb\u4f55\u64cd\u4f5c&quot;\n        \u2193\n\uff08\u5982\u679c\u7528\u6237\u70b9&quot;\u6279\u51c6&quot;\u2192 LLM \u7ee7\u7eed\u8c03 run_terminal\uff09\n        \u2193\n\u7b2c\u4e8c\u5c42\uff1aToolExecutor.classify(&quot;run_terminal&quot;) \u2192 &quot;execute&quot;\n         confirm_execute=True \u2192 \u518d\u5f39\u4e00\u6b21\u786e\u8ba4\n        \u2193\n\u7b2c\u4e00\u5c42\uff1arun_terminal \u5185\u90e8 \u2192 \u5173\u952e\u8bcd\u9ed1\u540d\u5355\u68c0\u67e5 \u2192 \u901a\u8fc7 \u2192 subprocess.run()\n<\/code><\/pre>\n<\/div>\n<p>\u4e09\u5c42\u4e32\u8054\u7684\u597d\u5904\u662f<strong>\u5373\u4f7f\u67d0\u4e00\u5c42\u6f0f\u4e86\u4e5f\u6709\u515c\u5e95<\/strong>\uff1a<br \/>\n&#8211; LLM \u5fd8\u4e86\u8c03 human_confirm \u2192 ToolExecutor \u7684 confirm_execute \u515c\u5e95\uff08CLI \u6bcf\u6b21 execute \u90fd\u5f39\uff09<br \/>\n&#8211; ToolExecutor \u56e0\u4e3a\u914d\u7f6e\u9519\u6f0f\u4e86 \u2192 \u5173\u952e\u8bcd\u9ed1\u540d\u5355\u515c\u5e95\uff08run_terminal \u5185\u90e8\u786c\u62e6\u622a\uff09<\/p>\n<hr \/>\n<h2 id=\"_5\">\u4e94\u3001\u5b89\u5168\u7b56\u7565\u7684\u5224\u5b9a\u8868<\/h2>\n<p>\u770b\u5b8c\u4e09\u5c42\u9632\u5fa1\uff0c\u6211\u7ed9\u4e00\u4e2a\u5b9e\u7528\u7684\u5224\u5b9a\u8868\u2014\u2014\u4f60\u7684 Agent \u81f3\u5c11\u9700\u8981\u54ea\u51e0\u5c42\uff1a<\/p>\n<table>\n<thead>\n<tr>\n<th>\u4f60\u7684 Agent \u573a\u666f<\/th>\n<th>\u7b2c\u4e00\u5c42\uff08\u786c\u62e6\u622a\uff09<\/th>\n<th>\u7b2c\u4e8c\u5c42\uff08ToolPolicy\uff09<\/th>\n<th>\u7b2c\u4e09\u5c42\uff08human_confirm\uff09<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u672c\u5730 demo\uff0c\u5de5\u5177\u53ea\u8bfb\uff08RAG\u3001\u77e5\u8bc6\u95ee\u7b54\uff09<\/td>\n<td>\u53ef\u9009\uff08\u6ca1\u6709 execute \u5de5\u5177\uff09<\/td>\n<td>\u4e0d\u9700\u8981<\/td>\n<td>\u4e0d\u9700\u8981<\/td>\n<\/tr>\n<tr>\n<td>\u672c\u5730 demo\uff0c\u6709 execute \u5de5\u5177\uff08run_terminal\uff09<\/td>\n<td><strong>\u5fc5\u987b<\/strong>\uff08AST \/ \u9ed1\u540d\u5355\uff09<\/td>\n<td><strong>\u5fc5\u987b<\/strong>\uff08allow_execute + confirm\uff09<\/td>\n<td>\u53ef\u9009<\/td>\n<\/tr>\n<tr>\n<td>Web UI\uff08\u7ed9\u522b\u4eba\u7528\uff09<\/td>\n<td><strong>\u5fc5\u987b<\/strong><\/td>\n<td><strong>\u5fc5\u987b<\/strong>\uff08Web \u7aef allow_execute=False\uff09<\/td>\n<td><strong>\u5fc5\u987b<\/strong><\/td>\n<\/tr>\n<tr>\n<td>\u751f\u4ea7\u73af\u5883\uff08\u591a\u4eba\u5171\u4eab\uff09<\/td>\n<td><strong>\u5fc5\u987b<\/strong><\/td>\n<td><strong>\u5fc5\u987b<\/strong>\uff08\u7ec6\u7c92\u5ea6 allowlist\uff09<\/td>\n<td><strong>\u5fc5\u987b<\/strong><\/td>\n<\/tr>\n<tr>\n<td>\u6709 MCP \u8fdc\u7aef\u5de5\u5177<\/td>\n<td><strong>\u5fc5\u987b<\/strong><\/td>\n<td><strong>\u5fc5\u987b<\/strong>\uff08mcp_allowlist\uff09<\/td>\n<td><strong>\u5fc5\u987b<\/strong>\uff08\u8fdc\u7aef\u5de5\u5177\u6743\u9650\u4e0d\u53ef\u63a7\uff09<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<h2 id=\"_6\">\u516d\u3001\u6f14\u8fdb\u65b9\u5411<\/h2>\n<table>\n<thead>\n<tr>\n<th>\u5c40\u9650<\/th>\n<th>\u73b0\u72b6<\/th>\n<th>\u6f14\u8fdb\u65b9\u5411<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u5173\u952e\u8bcd\u9ed1\u540d\u5355\u53ef\u7ed5\u8fc7<\/td>\n<td>PowerShell \u6362\u4e2a\u5199\u6cd5\u5c31\u7ed5<\/td>\n<td>PowerShell AST \u89e3\u6790\uff08<code>[Parser]::ParseInput<\/code>\uff09\u771f\u6b63\u7406\u89e3\u547d\u4ee4\u610f\u56fe<\/td>\n<\/tr>\n<tr>\n<td>ToolExecutor.classify \u9760\u5de5\u5177\u540d<\/td>\n<td>\u81ea\u5199\u7684\u672c\u5730\u5de5\u5177\u5982\u679c\u53eb <code>mcp_backup<\/code> \u4f1a\u88ab\u8bef\u5224\u4e3a MCP<\/td>\n<td>\u8ba9 callable \u52a0 <code>__risk__<\/code> \u5143\u5c5e\u6027\uff0cclassify \u4ece callable \u8bfb\u53d6<\/td>\n<\/tr>\n<tr>\n<td>human_confirm \u53ea\u6709 approve\/deny<\/td>\n<td>\u7528\u6237\u4e0d\u80fd&#8221;\u4fee\u6539\u547d\u4ee4\u540e\u518d\u6279\u51c6&#8221;<\/td>\n<td>\u8fd4\u56de\u7ed3\u6784\u5316\u7ed3\u679c\uff08approve \/ deny \/ modify \/ delegate\uff09<\/td>\n<\/tr>\n<tr>\n<td>ToolPolicy \u5168\u9760\u5e03\u5c14\u5f00\u5173<\/td>\n<td>\u4e0d\u591f\u7075\u6d3b\uff08\u6bd4\u5982&#8221;file_write \u53ea\u80fd\u5199 workspace \u76ee\u5f55&#8221;\uff09<\/td>\n<td>\u6bcf\u7c7b\u98ce\u9669\u7684 allowlist \u53ef\u4ee5\u662f\u4e00\u4e2a predicate \u51fd\u6570<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<h2 id=\"_7\">\u5ef6\u4f38\u9605\u8bfb<\/h2>\n<ul>\n<li><a href=\"..\/project\/\u8bbe\u8ba1\u51b3\u7b56\u6e05\u5355.md\">\u672c\u9879\u76ee\u8bbe\u8ba1\u51b3\u7b56\u6e05\u5355 &#8211; S1~S5<\/a><\/li>\n<li><a href=\"https:\/\/owasp.org\/www-project-top-10-for-large-language-model-applications\/\">OWASP Top 10 for LLM Applications<\/a><\/li>\n<li><a href=\"https:\/\/python.langchain.com\/docs\/concepts\/security\/\">LangChain Security Best Practices<\/a><\/li>\n<\/ul>\n<hr \/>\n<h2 id=\"_8\">\u672c\u7cfb\u5217\u5176\u4ed6\u6587\u7ae0<\/h2>\n<ul>\n<li>\u2705 \u7b2c 1 \u7bc7\uff1a<a href=\".\/01-Function-Calling-\u6781\u7b80\u5b9e\u73b0.md\">LLM Agent \u6781\u7b80\u5b9e\u73b0\uff1a200 \u884c\u4ee3\u7801\u8dd1\u901a Function Calling \u5168\u6d41\u7a0b<\/a><\/li>\n<li>\u2705 \u7b2c 2 \u7bc7\uff1a<a href=\".\/02-\u5355\u4e00\u771f\u76f8\u6e90\u4e0ePrompt\u6f02\u79fb.md\">Agent \u9879\u76ee\u7684\u5355\u4e00\u771f\u76f8\u6e90 \u2014 \u5f53 CLI \u548c Web UI \u7684 Prompt \u5f00\u59cb\u6f02\u79fb\u65f6<\/a><\/li>\n<li>\u2705 \u7b2c 3 \u7bc7\uff1a<a href=\".\/03-Skill\u505a\u6210Markdown.md\">\u628a Skill \u505a\u6210 Markdown \u6587\u4ef6 \u2014 Agent \u6846\u67b6\u7684&#8221;\u4f4e\u4ee3\u7801&#8221;\u8bbe\u8ba1\u51b3\u7b56<\/a><\/li>\n<li>\u2705 \u7b2c 4 \u7bc7\uff1a\u4f60\u6b63\u5728\u8bfb\u7684\u8fd9\u7bc7<\/li>\n<li>\ud83d\udcdd <a href=\".\/05-Gold-Case\u8bc4\u6d4b\u6846\u67b6.md\">\u7b2c 5 \u7bc7\uff1aAgent \u4e0d\u662f Demo \u2014 \u5982\u4f55\u7528 20 \u6761 Gold Case \u642d\u5efa\u53ef\u81ea\u52a8\u8fd0\u884c\u7684\u8bc4\u6d4b\u6846\u67b6<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>\u4f5c\u8005\uff1aAgent Dev \u5b9e\u8df5\u7b14\u8bb0 | \u53d1\u5e03\u65e5\u671f\uff1a2026-09-21 | \u6807\u7b7e\uff1aAgent, \u5b89\u5168, AST, Human-in-the-loop, Tool Policy<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1825","post","type-post","status-publish","format-standard","hentry","category-unknown"],"_links":{"self":[{"href":"https:\/\/www.liujh168.com\/index.php\/wp-json\/wp\/v2\/posts\/1825","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.liujh168.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.liujh168.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.liujh168.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.liujh168.com\/index.php\/wp-json\/wp\/v2\/comments?post=1825"}],"version-history":[{"count":0,"href":"https:\/\/www.liujh168.com\/index.php\/wp-json\/wp\/v2\/posts\/1825\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.liujh168.com\/index.php\/wp-json\/wp\/v2\/media?parent=1825"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.liujh168.com\/index.php\/wp-json\/wp\/v2\/categories?post=1825"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.liujh168.com\/index.php\/wp-json\/wp\/v2\/tags?post=1825"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}