Microsoft Agent Framework Skills 执行 Scripts(实战指南)
<p>在 Microsoft Agent Framework 中,<strong>Agent Skills</strong> 是一个非常重要但容易被忽略的能力。它可以让你的 Agent 拥有“插件化能力”,甚至可以执行本地脚本(如 Python),实现真正的自动化。</p><p>本文结合完整示例,带你从 <strong>原理 → 结构 → 实战 → 坑点</strong> 全面掌握如何通过 Skills + 自定义 Tool,实现执行 Python 脚本。</p>
<hr>
<h2 id="一什么是-agent-skills">一、什么是 Agent Skills?</h2>
<p>官方定义:</p>
<blockquote>
<p>Agent Skills 是一组可移植的指令、脚本和资源,用于为 Agent 提供特定能力。</p>
</blockquote>
<p>简单理解就是给 Agent 安装“技能包”,比如:</p>
<ul>
<li>数据分析 skill</li>
<li>报销审核 skill</li>
<li>会议纪要 skill(本文示例)</li>
</ul>
<hr>
<h2 id="二skill-目录结构">二、Skill 目录结构</h2>
<p>一个标准 Skill 结构如下:</p>
<pre><code>skills/
└── meeting-notes/
├── SKILL.md
└── scripts/
└── GetMeetingNotes.py
</code></pre>
<h3 id="1-skillmd核心">1. SKILL.md(核心)</h3>
<pre><code class="language-yaml">---
name: meeting-notes
description: Various python scripts for meeting-notes
---
</code></pre>
<pre><code class="language-md"># The meeting notes
(meeting-notes/scripts/GetMeetingNotes.py)
Give above script-path to a 'execute_python' tool
</code></pre>
<p>关键点:</p>
<ul>
<li><code>name</code> 必须和目录一致</li>
<li><code>description</code> 用于让 Agent 判断是否使用该 skill</li>
<li>markdown 内容 = <strong>操作说明</strong></li>
</ul>
<h3 id="2-python-script">2. Python Script</h3>
<pre><code class="language-python">def main():
return "Chester completed the create user api, and need implement the update user api"
if __name__ == "__main__":
print(main())
</code></pre>
<p>说明:</p>
<ul>
<li>定义 <code>main()</code></li>
<li>最后 <code>print</code> 输出</li>
</ul>
<hr>
<h2 id="三关键问题c-目前不支持自动执行-scripts">三、关键问题:C# 目前不支持自动执行 scripts</h2>
<p>官方文档明确说明:</p>
<blockquote>
<p>Script execution is not yet supported in C#</p>
</blockquote>
<p>所以:</p>
<ul>
<li>❌ Agent 不会自动执行 <code>.py</code></li>
<li>✅ 需要自己提供 Tool</li>
</ul>
<hr>
<h2 id="四核心实现自定义-python-执行器">四、核心实现:自定义 Python 执行器</h2>
<h3 id="pythonrunnercs">PythonRunner.cs</h3>
<pre><code class="language-csharp">public static class PythonRunner
{
public static string RunPhytonScript(string pythonFilePath)
{
if (string.IsNullOrWhiteSpace(pythonFilePath))
throw new ArgumentException("File path cannot be empty.", nameof(pythonFilePath));
pythonFilePath = Path.Combine(AppContext.BaseDirectory, "skills", pythonFilePath);
if (!File.Exists(pythonFilePath))
throw new FileNotFoundException("Python file not found.", pythonFilePath);
if (!string.Equals(Path.GetExtension(pythonFilePath), ".py", StringComparison.OrdinalIgnoreCase))
throw new ArgumentException("File must have a .py extension.", nameof(pythonFilePath));
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "python",
Arguments = "\"" + pythonFilePath + "\"",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
StandardOutputEncoding = Encoding.UTF8,
StandardErrorEncoding = Encoding.UTF8
};
using (Process process = new Process { StartInfo = startInfo })
{
process.Start();
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
process.WaitForExit();
if (process.ExitCode != 0 || !string.IsNullOrWhiteSpace(error))
throw new InvalidOperationException(
"Python script failed. ExitCode=" + process.ExitCode + Environment.NewLine + error.Trim());
return output.TrimEnd();
}
}
}
</code></pre>
<hr>
<h2 id="五把-python-执行能力变成-agent-tool">五、把 Python 执行能力变成 Agent Tool</h2>
<h3 id="programcs">Program.cs</h3>
<pre><code class="language-csharp">Tools = [
AIFunctionFactory.Create(
PythonRunner.RunPhytonScript,
name: "execute_python"
)
]
</code></pre>
<p>关键点:</p>
<ul>
<li>方法暴露为 Tool</li>
<li>名字必须和 SKILL.md 里的说明一致</li>
</ul>
<hr>
<h2 id="六skills--tool-协作流程">六、Skills + Tool 协作流程</h2>
<pre><code>用户输入
↓
Agent 发现 skills(Advertise)
↓
判断匹配 meeting-notes skill
↓
load_skill(加载 SKILL.md)
↓
理解指令:"调用 execute_python"
↓
调用 Tool
↓
执行 Python
↓
返回结果
</code></pre>
<hr>
<h2 id="七运行效果">七、运行效果</h2>
<p>用户输入:</p>
<pre><code>帮我获取会议纪要
</code></pre>
<p>Agent 内部行为:</p>
<ol>
<li>发现 <code>meeting-notes</code></li>
<li>读取 SKILL.md</li>
<li>找到执行说明:</li>
</ol>
<pre><code>Give above script-path to a 'execute_python' tool
</code></pre>
<ol start="4">
<li>调用:</li>
</ol>
<pre><code>execute_python("meeting-notes/scripts/GetMeetingNotes.py")
</code></pre>
<p>最终输出:</p>
<pre><code>Chester completed the create user api, and need implement the update user api
</code></pre>
<hr>
<h2 id="八关键设计模式">八、关键设计模式</h2>
<h3 id="patternskill-负责决策tool-负责执行">Pattern:Skill 负责“决策”,Tool 负责“执行”</h3>
<table>
<thead>
<tr>
<th>层级</th>
<th>作用</th>
</tr>
</thead>
<tbody>
<tr>
<td>Skill</td>
<td>告诉 Agent 做什么</td>
</tr>
<tr>
<td>Tool</td>
<td>真正执行</td>
</tr>
</tbody>
</table>
<p>说明:</p>
<ul>
<li>Skill ≠ 代码执行</li>
<li>Skill = Prompt + 指南</li>
</ul>
<hr>
<h2 id="九安全建议">九、安全建议</h2>
<p>执行脚本属于高风险操作,需要注意:</p>
<h3 id="1-限制路径">1. 限制路径</h3>
<pre><code class="language-csharp">skills/xxx
</code></pre>
<p>避免执行系统敏感目录,如:</p>
<pre><code>../../../../system32
</code></pre>
<h3 id="2-白名单机制">2. 白名单机制</h3>
<p>只允许执行:</p>
<pre><code>scripts/*.py
</code></pre>
<h3 id="3-沙箱运行">3. 沙箱运行</h3>
<ul>
<li>Docker</li>
<li>限制权限</li>
<li>禁止网络访问(必要时)</li>
</ul><br><br>
来源:https://www.cnblogs.com/chenyishi/p/19760871
頁:
[1]