用 Semantic Kernel 多 Agent 协作自动生成代码库技术文档:Document Generator 示例全解析
【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel
本文以 Semantic Kernel Python 仓库中的 Document Generator 示例 为主体,讲解如何用多 Agent(内容创作、代码校验、用户反馈)协同完成"针对某个代码库自动撰写技术文档"的完整流程,并深入剖析其插件设计、Agent 选择策略、终止策略与 OpenTelemetry 可观测性埋点。读完本文,你将掌握基于 Semantic Kernel Agent Framework 搭建可监控的多 Agent 写作流水线的思路与全部关键代码细节。
一、示例概览:AI 如何为代码库自动写技术文档
Document Generator 是一个演示型示例应用,位于 python/samples/demos/document_generator。它的目标是用 AI 为一个代码库自动生成技术文档——具体来说,它编排多个 Agent 协作,围绕 Semantic Kernel 自身的 AI 连接器(AI Connectors)写出一篇技术博客式的文档。
示例应用还内置了遥测(telemetry)能力,用于监控各 Agent 的运行过程,让开发者能观察到 Agent 内部究竟如何协作。这一点在多 Agent 系统中尤为重要:最终产出的文档只是结果,而"多个 Agent 如何轮流发言、谁在何时做了什么、它们如何互相影响"才是值得观察的过程。
需要强调的是,由于 AI 模型的随机性(stochastic nature),该示例无法保证每次都生成完美的文档。仓库中附带了一份由应用实际生成的示例产物 GENERATED_DOCUMENT.md,可作为预期输出质量的参考(它以 "Understanding Semantic Kernel AI Connectors" 为主题,包含自定义连接器的分步教程与可用代码示例)。
二、整体设计:三大插件与三个 Agent 的分工
2.1 三个工具/插件(Plugins)
示例为 AI 准备了三个插件,分别解决"读源码""跑代码""问用户"三类需求:
- Code Execution Plugin(代码执行插件):提供沙箱环境执行 Python 代码片段,返回程序输出或报错信息。实现见 code_execution_plugin.py,它封装了
AICodeSandbox,固定使用python:3.12-slim镜像并预装semantic_kernel包。 - Repository File Plugin(仓库文件插件):允许 AI 从 Semantic Kernel 仓库中检索文件,用于阅读它认为必要参考的源码。实现见 repo_file_plugin.py,提供
read_file_by_path、read_file_by_name、list_directory三个@kernel_function。 - User Input Plugin(用户输入插件):允许 AI 将内容呈现给用户并接收反馈。实现见 user_plugin.py,其
request_user_feedback函数本质是调用 Python 内置的input()在终端向用户索要反馈。
三个插件都通过@kernel_function装饰器暴露为 SK 函数,从而可以被 LLM 按需调用(function calling)。
2.2 三个 Agent(智能体)
- Content Creation Agent(内容创作 Agent):负责创作文档正文,持有 Repository File Plugin,可自行读取源码作为参考。对应实现 content_creation_agent.py。
- Code Validation Agent(代码校验 Agent):负责校验文档中的代码片段是否可运行,持有 Code Execution Plugin 执行代码。对应实现 code_validation_agent.py。
- User Agent(用户 Agent):负责与用户交互,持有 User Input Plugin 把草稿呈现给用户并收集反馈。对应实现 user_agent.py。
三者均继承自 custom_agent_base.py 中的CustomAgentBase,后者继承 Semantic Kernel 的ChatCompletionAgent。
2.3 调度核心:AgentGroupChat 与两个自定义策略
主程序 main.py 将三个 Agent 放入AgentGroupChat,并注入自定义的 Agent 选择策略与终止策略:
group_chat = AgentGroupChat( agents=agents, termination_strategy=CustomTerminationStrategy(agents=agents), selection_strategy=CustomSelectionStrategy(), ) await group_chat.add_chat_message( ChatMessageContent(role=AuthorRole.USER, content=TASK.strip()) ) async for response in group_chat.invoke(): print(f"==== {response.name} just responded ====")版本提示:
main.py头部注释明确说明,本示例使用的是 Semantic Kernel 的AgentGroupChat特性,该特性已不再维护。官方建议迁移到GroupChatOrchestration(相关迁移指南见官方 Learn 文档)。阅读与复用时请注意这一演进。
2.4 任务提示词(TASK)
示例要 AI 完成的任务定义在main.py的TASK字符串中:围绕"Semantic Kernel 的 AI Connectors"写一篇技术博客,要求覆盖三个问题——什么是 AI 连接器、开发者如何使用、如何创建自定义连接器(含分步教程与可运行的示例)。为了让内容创作 Agent 有的放矢,任务里还指明了应当参考的源码文件,例如:
semantic_kernel/connectors/ai/chat_completion_client_base.pysemantic_kernel/services/ai_service_client_base.pysemantic_kernel/connectors/ai/ollama/services/ollama_chat_completion.pysemantic_kernel/connectors/ai/open_ai/services/open_ai_chat_completion_base.pysemantic_kernel/contents/chat_history.py
这正是"代码库技术文档生成"类应用的关键设计:把源码路径作为任务的检索线索喂给 AI,再由 Repository File Plugin 实际读取。
三、三个 Agent 的源码级实现剖析
3.1 公共基类 CustomAgentBase:服务创建与消息归一化
custom_agent_base.py 中定义了Services枚举(openai/azure_openai)与CustomAgentBase。它有两个关键职责:
- 按枚举创建 AI 服务:
_create_ai_service()通过match语句分别构造AzureChatCompletion(默认,使用AzureCliCredential进行 Azure CLI 身份认证)或OpenAIChatCompletion,并支持instruction_role参数(system或developer,默认system)。 - 重写
invoke():先把输入消息归一化为ChatMessageContent列表,并过滤掉content为空的"纯函数调用/函数结果"消息,避免污染上下文;同时支持追加一条additional_user_message。
3.2 Content Creation Agent:生成与修订内容
content_creation_agent.py 的INSTRUCTION系统提示词要求它"生成富有信息量且吸引人的技术内容,包含代码片段",并"吸收反馈后给出更新后的完整内容"。
关键细节:它重写了invoke(),每次被选中发言时都会追加一条固定消息"Now generate new content or revise existing content to incorporate feedback.",确保无论处于首次创作还是修订阶段,行为都符合预期。其DESCRIPTION为"Select me to generate new content or to revise existing content."——该描述会被选择策略读取,用于决定下一轮该谁发言。
3.3 Code Validation Agent:校验文档中的代码
code_validation_agent.py 的系统提示词定义了严谨的校验工作流:将最新草稿中的 Python 片段拼装成单一脚本(若片段来自多个脚本则改造为可协同工作的整体)、执行验证、汇总错误信息,且明确禁止自行修复错误("Do not try to fix the errors.")。它每次发言追加的固定消息是"Now validate the Python code in the latest document draft and summarize any errors."。
这种"校验者只报告、不修复"的设计,让错误修复职责自然流转回 Content Creation Agent,形成清晰的闭环。
3.4 User Agent:把草稿交给人审
user_agent.py 负责"把最新草稿呈现给用户并总结反馈",同样不负责处理反馈("Do not try to address the user's feedback in this chat.")。其底层调用 user_plugin.py 的request_user_feedback(),直接在终端打印内容并等待用户输入:
@kernel_function(description="Present the content to user and request feedback.") def request_user_feedback( self, content: Annotated[str, "The content to present and request feedback on."] ) -> Annotated[str, "The feedback provided by the user."]: return input(f"Please provide feedback on the content:\n\n{content}\n\n> ")由此,人机协作被无缝纳入多 Agent 会话:Agent 需要用户拍板时,会真的停下来等待人在终端里打字。
四、Agent 选择策略:谁该接着发言
README 中"Agent Selection Strategy"与"Termination Strategy"两节没有展开细节,但源码给出了完整答案。
custom_selection_strategy.py 中的CustomSelectionStrategy继承 Semantic Kernel 的SelectionStrategy,核心逻辑在next()方法:
- 构造一个
ChatHistory,system 消息由get_system_message()生成,其中以[index] agent.name + description的形式列出全部 Agent 及其描述。 - 把会话历史中所有非空文本消息加入上下文(跳过纯函数调用/函数结果消息)。
- 追加用户消息,要求模型"按规则选择下一位 Agent,只输出其索引号"。
- 使用独立的
OpenAIChatCompletion()(通过Field(default_factory=...)创建)调用get_chat_message_content()获取索引;最多重试NUM_OF_RETRIES = 3次;若模型输出无法解析为整数,则把该输出与纠错提示("You must only say a number between 0 and N-1")回灌进历史后重试;最终仍失败则抛出ValueError。
系统提示词中嵌入了完整的会话编排规则,例如:内容创作 Agent 先写草稿 → 代码校验 Agent 检查代码 → 内容创作 Agent 依据反馈更新 → 再校验……当校验通过后,User Agent 向用户征求最终意见;若反馈不乐观,则回到内容创作 Agent。这解释了为什么DESCRIPTION字段如此重要——它是选择策略做出决策的主要依据。
值得注意的实现细节:选择策略的每次决策都包裹在 OpenTelemetry span"selection_strategy"中(见下文第五节),方便追踪"谁选了谁"。
五、终止策略:何时结束整场会话
custom_termination_strategy.py 中的CustomTerminationStrategy继承TerminationStrategy,设置maximum_iterations = 20作为会话轮次硬上限,防止 Agent 无限对话。
should_agent_terminate()的逻辑同样交给 LLM 判断:把历史消息与 Agent 清单放入ChatHistory,追问"最新内容是否已被所有 Agent 批准?只回答yes或no";在NUM_OF_RETRIES = 3次重试内解析响应中是否包含关键词yes/no,若模型答非所问则回灌"只能回答 yes 或 no"的纠错消息后重试,最终无果则抛异常。每次判断同样包裹在名为"terminate_strategy"的 span 中。
从源码结构可以看出这套终止判定的设计思路:把"是否达成共识"也交给模型来评估,而不是硬编码规则,从而与选择策略共同形成一个由 LLM 驱动的、动态的会话编排闭环。
六、运行前置条件与沙箱代码执行
6.1 依赖与前置条件
按 README,运行该示例需要:
- Azure OpenAI(默认服务,见
custom_agent_base.py中默认Services.AZURE_OPENAI)。 - Azure Application Insights(可选,用于遥测监控)。
额外的 Python 包AICodeSandbox用于在沙箱中执行 AI 生成的代码:
pip install ai-code-sandbox使用沙箱需要本机已安装并运行Docker。代码执行时若本地没有对应镜像会自动拉取,执行期间会创建容器、结束后销毁容器。相关实现见 code_execution_plugin.py:每次执行都新建
AICodeSandbox(custom_image="python:3.12-slim", packages=["semantic_kernel"]),并在finally中调用sandbox.close()释放资源。
6.2 环境变量配置
示例支持两种 AI 服务,通过环境变量区分。OpenAI方式:
OPENAI_CHAT_MODEL_ID=<model-id> OPENAI_API_KEY=<your-key>官方示例生成 GENERATED_DOCUMENT.md 时使用的是
gpt-4o-2024-08-06。README 说明可以自由换用其他模型或其他提供商的模型,但换提供商时需同步更新custom_agent_base.py中的 chat completion 服务创建逻辑(即_create_ai_service()的match分支)。
Azure OpenAI方式:
AZURE_OPENAI_CHAT_DEPLOYMENT_NAME=<deployment-name> AZURE_OPENAI_ENDPOINT=<endpoint> # in the form of `https://<resource>.openai.azure.com/` AZURE_OPENAI_API_KEY=<api-key> # only required if using api key auth AZURE_OPENAI_API_VERSION=<api-version> # optional, defaults to the latest Azure OpenAI GA API version of `2024-10-21` if not provided其中AZURE_OPENAI_API_VERSION可选,缺省时使用 2024-10-21 版本的 Azure OpenAI GA API。custom_agent_base.py的注释还提示:若使用 Azure OpenAI 且走 API Key 认证,AZURE_OPENAI_API_KEY必须存在;示例默认采用AzureCliCredential()进行 Azure CLI 身份认证。
6.3 启动应用
在python/samples/demos/document_generator目录下运行:
python ./main.py预期输出形如:
==== ContentCreationAgent just responded ==== ==== CodeValidationAgent just responded ==== ==== ContentCreationAgent just responded ==== ...main.py在会话结束后会从group_chat.get_chat_messages(agent=agents[0])中筛选出 Content Creation Agent 自己产出的消息(该历史是倒序返回的),取最新一条打印为最终文档。
七、自定义与扩展:把示例改造成自己的写作流水线
README 明确指出这是"面向 Semantic Kernel AI connectors 技术文档"的示例,可按需定制:
- 换一个任务:修改
main.py中的TASK提示词。 - 新增 Agent:在 agents/ 下新建 Agent 类,并加入
main.py的agents列表。 - 调教已有 Agent:修改各 Agent 源码中的
INSTRUCTION提示词。 - 更换选择策略:修改 custom_selection_strategy.py。
- 更换终止策略:修改 custom_termination_strategy.py。
理解这些扩展点的关键是认清分工:Agent 的DESCRIPTION供选择策略使用,INSTRUCTION定义行为边界,插件提供工具能力,TASK定义终极目标——四者共同决定整个流水线的产出质量。
八、可选进阶:用 OpenTelemetry 监控 Agent 内部协作
8.1 为什么需要额外埋点
Semantic Kernel 默认会为所有 LLM 调用埋点,但Agent 本身没有默认的 instrumentation。因此示例展示了如何为 Agent 扩展可观测性。README 同时提示:Agent 的概念尚新,业界还没有统一的 Agent 信息采集标准(Agent 的 OpenTelemetry Semantic Convention 仍处于草案阶段)。
8.2 遥测环境变量
AZURE_APP_INSIGHTS_CONNECTION_STRING=<your-connection-string> SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS=true SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS_SENSITIVE=true前两个开关分别启用 Semantic Kernel 的 OpenTelemetry 诊断(实验特性)及敏感信息级别的诊断。
8.3 源码中的埋点实现
main.py 中的set_up_tracing()与set_up_logging()完成初始化:前者用TracerProvider+BatchSpanProcessor+AzureMonitorTraceExporter建立 trace 导出链路,并以SERVICE_NAME: "Document Generator"作为资源属性;后者用LoggerProvider+LoggingHandler把 Python 标准库日志以 OTLP 格式转发给 Application Insights,并设置logging.INFO级别。只有设置了AZURE_APP_INSIGHTS_CONNECTION_STRING时才会执行初始化。
随后可以看到贯穿整个应用的手工埋点:
main()的主流程包在tracer.start_as_current_span("main")中;- 选择策略每次选人包在
"selection_strategy"span 中(custom_selection_strategy.py); - 终止策略每次判定包在
"terminate_strategy"span 中(custom_termination_strategy.py)。
由此,整场会话的"谁发言、谁被选中、何时判定结束"都成为可查询的 trace 数据。官方文档提供了两种查看方式:通过 Application Insights 检查遥测数据,或在 Azure AI Foundry 的 tracing UI 中可视化 trace 数据。
九、小结
Document Generator 是一个小而完整的多 Agent 协作范本,其价值可以拆成四层:
- 插件层:用三个
@kernel_function插件分别赋予 Agent"读仓库源码""沙箱跑代码""询问真人"的能力; - Agent 层:内容创作、代码校验、用户交互三角色各司其职,通过
DESCRIPTION暴露自己的能力画像; - 编排层:用自定义
SelectionStrategy(LLM 按索引选人)与TerminationStrategy(LLM 判定是否达成共识 + 20 轮硬上限)驱动会话自动流转; - 可观测层:借 OpenTelemetry 为 Agent 会话补齐 trace 与日志,让黑盒协作过程变得可查。
对于任何需要"让多个 AI 角色协作完成一份复杂产出"的场景——技术文档、博客、代码评审、报告生成——本示例的设计模式都值得直接借鉴。若要在自己的项目中使用,请注意AgentGroupChat已停止维护,官方建议迁移到GroupChatOrchestration,迁移时本文剖析的选择/终止策略定制思路依然适用。
【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考