基于 Semantic Kernel Process Framework 与 Cloud Events 的跨进程文档生成实战

发布时间:2026/11/14 1:21:53

基于 Semantic Kernel Process Framework 与 Cloud Events 的跨进程文档生成实战 基于 Semantic Kernel Process Framework 与 Cloud Events 的跨进程文档生成实战【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel导读本文围绕 Semantic Kernel.NET的 Process Framework 展开通过仓库中开箱即用的ProcessWithCloudEvents示例文档生成工作流完整讲解如何让 SK Process 通过自定义 Cloud Event 通道对外发送外部事件、接收外部输入事件并与 gRPC 服务端、Dapr Actor 运行时及 React Web 客户端无缝集成。读完本文你将掌握IExternalKernelProcessMessageChannel的完整实现契约、ProcessBuilder.AddProxyStep与EmitExternalEvent的编排方式以及一套可复制的事件进、事件出进程集成方案。示例总览三个工程的分工示例位于仓库的 dotnet/samples/Demos/ProcessWithCloudEvents由三个相对独立的工程组成工程职责ProcessWithCloudEvents.Processes包含与运行时无关的 Process Builder 定义、步骤Step、模型与数据结构可被任何宿主复用ProcessWithCloudEvents.Grpc基于 Dapr 的 gRPC 服务器通过 gRPC 与 Processes 工程中定义的进程交互同时承载 Dapr Actor 运行时ProcessWithCloudEvents.Client基于 ReactJSVite TypeScript的 Web 应用用于从 UI 侧发送/接收 Cloud Event与运行中的 SK Process 交互从源码结构看这种进程定义与进程宿主分离的设计正是 Process Framework 推荐的形态进程逻辑DocumentGenerationProcess.cs可以在不同运行时本地、Dapr、云事件通道下复用宿主工程只负责注入通道实现与依赖。Document Generation Process事件驱动的文档生成流水线示例的核心是一个模拟用户请求某产品的文档生成的 SK Process。它由 DocumentGenerationProcess.cs 定义包含如下步骤StepGather Product Info Step采集产品信息示例中返回虚构的 GlowBrew 咖啡机资料Generate Documentation StepGenerateDocs调用 LLM 生成面向客户的文档Proof Read Documentation Step调用 LLM 校对文档判定通过或驳回Proxy Step将文档以外部事件形式发送给用户审批Publish Documentation Step用户批准后发布文档Generate Documentation StepApplySuggestions用户驳回时按建议重写文档Proxy Step将最终发布的文档对外发送。对应的事件流来自原文档Mermaid 表述如下进程对外发事件SK Process 内的 SK 事件被路由到 Proxy Step由 Proxy Step 通过外部消息通道发往外部系统进程收外部事件SK 输入事件Input Event在外部被触发后送入进程驱动流程继续。事件与主题Events vs Topics的语义区分源码中将进程内部事件与对外主题分开定义这是理解 Cloud Event 集成的关键public static class DocGenerationEvents { public const string StartDocumentGeneration nameof(StartDocumentGeneration); public const string UserRejectedDocument nameof(UserRejectedDocument); public const string UserApprovedDocument nameof(UserApprovedDocument); } public static class DocGenerationTopics { public const string RequestUserReview nameof(RequestUserReview); public const string PublishDocumentation nameof(PublishDocumentation); }EventsSK Process 事件进程内部流转的事件如StartDocumentGeneration用于启动进程UserRejectedDocument/UserApprovedDocument用于外部审批结果回灌Topics对外主题进程需要暴露给外部系统的语义主题如RequestUserReview请求用户评审与PublishDocumentation发布文档。主题经 Proxy Step 映射为具体的通道调用如 gRPC 方法。进程编排代码逐段解析完整的进程构建逻辑位于 DocumentGenerationProcess.cs第一步注册步骤并添加 Proxy Stepvar infoGatheringStep processBuilder.AddStepFromTypeGatherProductInfoStep(); var docsGenerationStep processBuilder.AddStepFromTypeGenerateDocumentationStep(); var docsProofreadStep processBuilder.AddStepFromTypeProofReadDocumentationStep(); var docsPublishStep processBuilder.AddStepFromTypePublishDocumentationStep(); var proxyStep processBuilder.AddProxyStep(id: processName, [DocGenerationTopics.RequestUserReview, DocGenerationTopics.PublishDocumentation]);AddProxyStep接收两个参数代理步骤的 id这里复用了进程名DocumentationGeneration以及该代理负责对外发送的主题列表。第二步编排外部输入事件processBuilder .OnInputEvent(DocGenerationEvents.StartDocumentGeneration) .SendEventTo(new(infoGatheringStep)); processBuilder .OnInputEvent(DocGenerationEvents.UserRejectedDocument) .SendEventTo(new(docsGenerationStep, functionName: GenerateDocumentationStep.ProcessFunctions.ApplySuggestions)); processBuilder .OnInputEvent(DocGenerationEvents.UserApprovedDocument) .SendEventTo(new(docsPublishStep, parameterName: userApproval));三个外部输入事件分别路由到不同目标启动事件进入信息采集步骤用户驳回事件进入GenerateDocumentationStep的ApplySuggestions函数用户批准事件进入PublishDocumentationStep的userApproval参数。第三步连接内部步骤并配置外部事件发射docsProofreadStep .OnEvent(ProofReadDocumentationStep.OutputEvents.DocumentationApproved) .EmitExternalEvent(proxyStep, DocGenerationTopics.RequestUserReview) .SendEventTo(new ProcessFunctionTargetBuilder(docsPublishStep, parameterName: document)); docsPublishStep .OnFunctionResult() .EmitExternalEvent(proxyStep, DocGenerationTopics.PublishDocumentation);这两段代码演示了EmitExternalEvent的典型用法在证明校对步骤发出DocumentationApproved事件时既把文档发送给发布步骤进程内部继续又通过 Proxy Step 以RequestUserReview主题对外发出审批请求发布步骤函数执行完成后再以PublishDocumentation主题对外广播。步骤实现要点各步骤的实现可以进一步印证事件的流转细节GenerateDocumentationStep.cs实现为KernelProcessStepGenerateDocumentationState在ActivateAsync中初始化ChatHistory通过GenerateDocs与ApplySuggestions两个[KernelFunction]分别完成初次生成与按建议重写二者都发射DocumentationGenerated输出事件。由于状态跨函数共享必须持久化在GenerateDocumentationState中。ProofreadDocumentationStep.cs使用 OpenAI 结构化输出ResponseFormat typeof(ProofreadingResponse)让 LLM 返回可解析的校对结论通过时发射DocumentationApproved且因该事件会暂停/恢复后续步骤如PublishDocumentationStep必须用KernelProcessEventVisibility.Public标记以保证持久化恢复驳回时携带改进建议字符串发射DocumentationRejected。PublishDocumentationStep.csOnPublishDocumentation(DocumentInfo document, bool userApproval)依据用户审批标志决定是否发布。GatherProductInfoStep.cs单函数步骤无需在[KernelFunction]中显式指定函数名。Setup如何让 SK Process 对接 Cloud Event 通道原文档给出了三条集成要点这里结合源码逐一展开1. 创建宿主服务器并启动 SK Process自定义服务器在收到外部请求时通过指定processId与输入事件启动或恢复一个 SK Process。在 gRPC 示例中DocumentGenerationService.UserRequestFeatureDocumentation 的启动逻辑如下var processId string.IsNullOrEmpty(request.ProcessId) ? Guid.NewGuid().ToString() : request.ProcessId; var process DocumentGenerationProcess.CreateProcessBuilder().Build(); var processContext await process.StartAsync(new KernelProcessEvent() { Id DocumentGenerationProcess.DocGenerationEvents.StartDocumentGeneration, Data new ProductInfo() { Title request.Title, Content request.Content, UserInput request.UserDescription }, }, processId, this._actorProxyFactory);未传processId时自动生成新的进程 idGuid.NewGuid()启动时注入的KernelProcessEvent.Data必须是目标步骤GatherProductInfoStep期望接收的ProductInfo类型传入IActorProxyFactory表明该进程运行在 Dapr Actor 之上实验性Process.Runtime.Dapr。类似地用户审批回传时通过UserReviewedDocumentation再次启动同一 processId 的进程并根据documentationApproved决定注入UserApprovedDocumentData 为true还是UserRejectedDocumentData 为驳回原因事件见 DocumentGenerationService.cs。2. 实现IExternalKernelProcessMessageChannel自定义通道实现必须包含三个成员这正是 Cloud Event 通道的核心契约成员职责Initialize初始建立与服务器的连接Uninitialize关闭与服务器的连接EmitExternalEventAsync向服务器发送外部事件可包含 SK 主题到具体服务器方法的内部映射gRPC 参考实现位于 DocumentGenerationGrpcClient.cs其EmitExternalEventAsync展示了主题到 gRPC 方法的映射public async Task EmitExternalEventAsync(string externalTopicEvent, KernelProcessProxyMessage message) { switch (externalTopicEvent) { case DocumentGenerationProcess.DocGenerationTopics.RequestUserReview: var requestDocument message.EventData.ToObject() as DocumentInfo; await this._grpcClient.RequestUserReviewDocumentationFromProcessAsync(new() { Title requestDocument.Title, AssistantMessage Document ready for user revision. Approve or reject document, Content requestDocument.Content, ProcessData new() { ProcessId message.ProcessId } }); return; case DocumentGenerationProcess.DocGenerationTopics.PublishDocumentation: // ... 映射为 _grpcClient.PublishDocumentationAsync(...) return; } }Initialize中创建指向http://localhost:58641的GrpcChannel对应服务端 Kestrel 的 Http2 端点Uninitialize中调用ShutdownAsync释放连接。3. 在 ProcessBuilder 中使用 Proxy Step原文档示例与 DocumentGenerationProcess.cs 一致var proxyStep processBuilder.AddProxyStep([DocGenerationTopics.RequestUserReview, DocGenerationTopics.PublishDocumentation]); // ... docsPublishStep .OnFunctionResult() .EmitExternalEvent(proxyStep, DocGenerationTopics.PublishDocumentation);需要理解的是Proxy Step 本身不执行业务逻辑它只是把进程内的 SK 事件翻译成对外通道调用EmitExternalEvent将事件指向 Proxy Step 并声明对外主题主题最终由通道实现的EmitExternalEventAsync映射为具体协议调用。宿主工程的装配DI、Dapr 与 gRPC 的完整接线Program.cs 给出了把以上三要素组合起来的完整宿主代码关键点包括// Kernel 与 OpenAI 聊天补全服务用户机密中配置 OpenAI:ChatModelId / OpenAI:ApiKey builder.Services.AddKernel(); builder.Services.AddOpenAIChatCompletion(openAIOptions.ChatModelId, openAIOptions.ApiKey); // 注入 SK Process 自定义 gRPC 客户端IExternalKernelProcessMessageChannel 实现 builder.Services.AddSingletonIExternalKernelProcessMessageChannel, DocumentGenerationGrpcClient(); // 配置 Dapr注册运行 Process 所需的 Actor builder.Services.AddActors(static options { options.AddProcessActors(); }); // gRPC 服务与反射、grpc-web 支持 builder.Services.AddGrpc(); builder.Services.AddGrpcReflection(); app.MapGrpcReflectionService().RequireCors(AllowAll); app.MapGrpcServiceDocumentGenerationService().EnableGrpcWeb().RequireCors(AllowAll); app.MapActorsHandlers();需要注意两点SK Process 运行在 Dapr Actor 之上因此必须调用options.AddProcessActors()示例同时启用了GrpcReflection与GrpcWeb配 CORS后者是 React Web 客户端能直接访问服务端的前提若不需要 Web 客户端可移除。服务端双端口配置见 appsettings.jsonhttp://*:58640使用 Http1 协议服务 grpc-webhttp://*:58641使用 Http2 协议服务原生 gRPC 客户端与 gRPCui。gRPC 契约六个方法构成的事件闭环documentationGenerator.proto 定义了六条 RPC恰好覆盖进程 ↔ 服务器 ↔ 客户端三个方向RPC 方法方向用途UserRequestFeatureDocumentation客户端 → 服务器请求生成文档服务器据此启动 SK ProcessRequestUserReviewDocumentationFromProcess进程 → 服务器SK Process 内由 Proxy 触发向订阅者推送待审文档RequestUserReviewDocumentation客户端 ← 服务器流客户端订阅指定 processId 的评审请求UserReviewedDocumentation客户端 → 服务器回传审批结果服务器注入审批事件到 SK ProcessPublishDocumentation进程 → 服务器SK Process 发布文档后广播给订阅者ReceivePublishedDocumentation客户端 ← 服务器流客户端订阅指定 processId 的已发布文档服务端 DocumentGenerationService.cs 使用ConcurrentDictionarystring, ConcurrentBagIServerStreamWriter...维护processId → 订阅者流的映射进程侧方法把消息写入所有订阅流RequestUserReviewDocumentationFromProcess、PublishDocumentation客户端订阅方法RequestUserReviewDocumentation、ReceivePublishedDocumentation则把调用方的响应流注册进映射并在客户端断开CancellationToken触发时移除形成完整的服务端流式推送闭环。端到端时序一次生成 → 审批 → 发布的完整旅程原文档用时序图清晰描述了 gRPC 事件全链路此处保留并标注对应源码位置gRPC 客户端调用UserRequestFeatureDocumentation服务器启动 SK Process 并发射StartDocumentGenerationSK 事件校对步骤触发DocumentationApproved事件时进程发射RequestUserReview主题经 Proxy Step 映射调用 gRPC 方法RequestUserReviewDocumentationFromProcess服务器将该消息写入共享订阅流已订阅RequestUserReviewDocumentation的客户端收到待审文档客户端通过UserReviewedDocumentation提交审批服务器据此向 SK Process 发射UserApprovedDocument或UserRejectedDocument事件对应 DocumentGenerationService.cs进程恢复执行PublishDocumentationStep获得全部参数文档 审批后运行随后发射PublishDocumentation主题调用服务器同名 gRPC 方法服务器更新ReceivePublishedDocumentation共享流所有订阅者收到最终发布的文档。运行与调试运行前置条件按 Grpc 工程 README 的说明准备好 Dapr 运行环境通过dotnet user-secrets或环境变量配置OpenAI:ChatModelId与OpenAI:ApiKey配置模型见 OpenAIOptions.cs必填校验由 ConfigurationExtension.cs 完成构建并运行应用。无 UI 交互方式使用 gRPCui安装并运行gRPCui监听localhost:58641./grpcui.exe -plaintext localhost:58641推荐打开多个 gRPCui 窗口分别执行不同方法并统一使用相同的processId例如100按以下顺序调用订阅评审RequestUserReviewDocumentation请求体{ processId: 100 }超时建议设 30 秒订阅该进程的评审推送发起生成UserRequestFeatureDocumentation请求体{ title: some product title, userDescription: some user description, content: some product content, processId: 100 }该请求会以指定 processId 启动一个新进程并注入初始事件收到评审推送后订阅发布ReceivePublishedDocumentation请求体{ processId: 100 }提交审批UserReviewedDocumentation请求体{ documentationApproved: true, reason: , processData: { processId: 100 } }documentationApproved为true时走UserApprovedDocument分支发布文档为false时走UserRejectedDocument分支带reason触发重写。使用 Web 客户端React 客户端ProcessWithCloudEvents.Client通过 gRPC Web 与localhost:58640通信安装依赖并启动开发服务器见 Client READMEyarn install yarn run dev浏览器访问http://localhost:5173在 UI 中发送事件/消息并实时观察服务端返回的事件流。调试建议两种方式任选其一安装 Visual Studio Dapr 扩展利用仓库根目录的 dotnet/dapr.yaml 配置启动调试或将ProcessWithCloudEvents.Grpc设为启动项目手动以 Dapr 方式运行并附加调试器dapr run --app-id processwithcloudevents-grpc --app-port 58640 --app-protocol http -- dotnet run --no-build小结ProcessWithCloudEvents示例完整演示了 SK Process Framework 与外部系统的三种集成范式进程内部事件驱动Step 间通过SendEventTo流转、进程对外事件发射AddProxyStepEmitExternalEventIExternalKernelProcessMessageChannel、外部事件回灌进程OnInputEvent 指定 processId 的StartAsync。其中 Dapr Actor 负责进程状态的持久化与恢复gRPC 服务端承担事件桥接React 客户端则验证了 grpc-web 场景下的可用性。对于要在自己应用中接入 Cloud Event 的开发者本文的三条主线可直接复用一是理解IExternalKernelProcessMessageChannel的Initialize/Uninitialize/EmitExternalEventAsync契约并按需实现gRPC、HTTP、消息队列皆可二是用 Proxy Step 显式声明对外主题保持进程内部逻辑与外部协议解耦三是把进程定义与宿主运行时拆分为独立工程让同一进程定义在不同基础设施上运行。【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/11 22:17:56

SAP Fiori Launchpad配置问题排查与优化指南

1. 项目概述:为什么需要系统化排查Fiori Launchpad内容?在SAP Fiori项目实施过程中,Launchpad作为用户接触系统的第一入口,其内容配置的准确性和完整性直接影响用户体验。我经历过多个项目,发现超过60%的Fiori权限问题…

2026/11/12 11:23:19

AI降噪工具实测:提升音频质量的关键技术与选型指南

1. 项目概述:AI降噪工具的实战价值 在数字内容创作领域,音频质量直接影响作品的专业度。作为从业12年的多媒体工程师,我亲历了从传统降噪到AI智能处理的完整技术迭代。2023年Q2行业报告显示,78%的创作者因背景噪音导致作品被平台降…

2026/11/14 1:17:03

电工证跟爬高证的区别全流程办理指南 电子证书如何转回本地

电工证跟爬高证的区别全流程办理指南 电子证书如何转回本地 之前考的证在外省能不能转过来,这个问题真的挺让人头疼。特别是像你这种在南阳卧龙区从事市政公用工程的朋友,经常要跨省跑项目,证件不通用、不能转,等于白忙活。好在现在 电子证书…

2026/11/14 1:17:03

杭州本地考高压电工证最新政策解读

30天从零拿到高压电工证:一个杭州人的真实经历 上个月,我在杭州一家工地做临时工,工资一天才150块,连住宿费都快不够。那天晚上我翻手机,看到一条招聘信息,写着“高压电工证持证上岗,月薪6000+”,我眼前一亮,这不就是我一直在等的机会吗?…

2026/11/14 1:17:03

特种工考试补助多少钱?学历不高也能拿补贴全流程详解

特种工考试补助多少钱?学历不高也能拿补贴全流程详解 学历不高怕报不上名?特种工考试补助多少钱?这些问题你是不是也问过?别担心,今天我就从河南培训机构学员的角度,把【特种工考试补助】的全流程讲清楚,从报考、考试到补贴申领,一文搞懂。…

2026/11/14 1:17:03

黄江哪里考电工证快速全国通用备考攻略

黄江哪里考电工证快速全国通用备考攻略 工地太忙根本没时间复习考试,尤其是像你这样在平顶山转岗的电工,时间紧任务重,想要快速拿到 全国通用…

2026/11/14 1:17:03

海南哪里考电工证好点?郑州报考避坑指南教你避坑

海南哪里考电工证好点?郑州报考避坑指南教你避坑 之前考的证在外省能不能转过来?这可能是很多在海南或打算在海南发展的电工最关心的问题。尤其是像你这样从信阳浉河区转岗过来的,可能手里拿着河南的电工证,担心到了海南能不能继续用。别急,我来给你理清…

2026/11/14 1:12:03

泸州哪里考电工证好通过率揭秘:实操考试心里没底怕挂科

泸州哪里考电工证好通过率揭秘:实操考试心里没底怕挂科 实操考试心里没底怕挂科?很多人第一次报考电工证时,都担心自己能不能一次性通过,尤其是对高压电工证、低压电工证这些实操内容要求高的工种。别担心,我们来揭开泸州哪里考电工证好通过率的真相,让…

2026/11/13 22:33:32

电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。…

2026/11/14 0:06:39

土木特种工考证官方报名入口怎么找 之前考的证在外省能不能转过来

土木特种工考证官方报名入口怎么找 之前考的证在外省能不能转过来 之前考的证在外省能不能转过来?这个问题我太熟悉了,作为一名干了十几年的特种作业证书办理从业者,每年都会遇到不少像你一样在外地考了证,回来却发现无法直接使用的学员。别急,今天我就…

2026/11/14 0:06:39

电工证要多久多钱保姆级教程:工地太忙根本没时间复习考试

电工证要多久多钱保姆级教程:工地太忙根本没时间复习考试 工地太忙根本没时间复习考试,你不是一个人。在信阳浉河区,很多刚进入工地的电工都面临这样的困境:工作强度大,时间碎片化,根本没有系统复习考试的机会。但电工证是上岗的硬门槛,…

2026/11/13 22:32:11

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/13 12:14:39

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑