
Semantic Kernel Process 与 gRPC 集成实战基于 Dapr 的云端事件双向通信指南【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel本指南以仓库中的 ProcessWithCloudEvents.Grpc/README.md 为核心深入讲解如何让 Semantic KernelSKProcess Framework 通过自定义 gRPC Server/Client 与外部客户端双向交换事件既能把进程内部的 SK 事件以 gRPC 方法形式推送给外部订阅者也能把外部客户端的审核结果以 SK 事件形式注回进程。读完本文你将掌握 SK Process 与 gRPC 集成时的端口规划、gRPC 反射与 gRPCui 调试、IExternalKernelProcessMessageChannel与ProxyStep的实现原理并能在本仓库中直接运行这套完整的文档生成审核演示。演示背景SK Process 与云事件该演示所在的 ProcessWithCloudEvents 目录下有三个相互协作的项目项目职责ProcessWithCloudEvents.Processes存放 Process Builder 定义、相关 Step、模型与数据结构不依赖具体运行时ProcessWithCloudEvents.Grpc基于 Dapr 的 gRPC Server通过 gRPC 与 Processes 项目中定义的进程交互ProcessWithCloudEvents.ClientReactJS 应用gRPC Web演示向运行中的 SK Process 发送和接收云事件其中ProcessWithCloudEvents.Grpc子目录即本文主体它演示了SK Process Framework 如何与 gRPC Server 及 gRPC 客户端交互。该演示与普通 gRPC 应用最大的区别在于SK Process 内部使用的 gRPC Server 与 Client 均为自定义实现由 SK Proxy Step 在进程内部调用。gRPC 仅作为承载云事件的传输通道业务状态机完全由 SK Process 编排。核心 gRPC 组件主 gRPC 组件共三个均位于 ProcessWithCloudEvents.Grpc 目录proto 契约Protos/documentationGenerator.protogRPC ServerServices/DocumentGenerationService.csgRPC Client /IExternalKernelProcessMessageChannel实现Clients/DocumentGenerationGrpcClient.csproto 契约6 个 RPC 方法documentationGenerator.proto 定义了GrpcDocumentationGeneration服务共 6 个 RPCsyntax proto3; option csharp_namespace ProcessWithCloudEvents.Grpc.DocumentationGenerator; service GrpcDocumentationGeneration { rpc UserRequestFeatureDocumentation (FeatureDocumentationRequest) returns (ProcessData); rpc RequestUserReviewDocumentationFromProcess (DocumentationContentRequest) returns (Empty); rpc RequestUserReviewDocumentation (ProcessData) returns (stream DocumentationContentRequest); rpc UserReviewedDocumentation (DocumentationApprovalRequest) returns (Empty); rpc PublishDocumentation (DocumentationContentRequest) returns (Empty); rpc ReceivePublishedDocumentation (ProcessData) returns (stream DocumentationContentRequest); }从源码结构看这 6 个方法分成三类用途外部客户端 → SK Process发起/反馈UserRequestFeatureDocumentation发起文档生成请求、UserReviewedDocumentation提交审批结果SK Process → 外部客户端订阅推送RequestUserReviewDocumentation订阅审核请求服务端流、ReceivePublishedDocumentation订阅发布结果服务端流SK Process 内部回环Proxy 调用服务端RequestUserReviewDocumentationFromProcess、PublishDocumentation这两个方法由DocumentGenerationGrpcClient在进程内部调用。消息体方面FeatureDocumentationRequest携带title、userDescription、content与processId字段编号 10预留扩展空间DocumentationApprovalRequest通过documentationApproved布尔值与reason字符串表达审核结论ProcessData则统一封装processId作为所有订阅与回写的会话键。该 proto 在 ProcessWithCloudEvents.Grpc.csproj 中通过Protobuf IncludeProtos\documentationGenerator.proto GrpcServicesBoth /启用即同时生成 Server 与 Client 端代码。gRPC Server订阅者集合与 SK 事件注入DocumentGenerationService.cs 是 gRPC 服务端实现其构造函数注入了ILogger、Kernel与IActorProxyFactoryDapr Actor 代理工厂并维护两个并发订阅者集合private readonly ConcurrentDictionarystring, ConcurrentBagIServerStreamWriterDocumentationContentRequest _docReviewSubscribers; private readonly ConcurrentDictionarystring, ConcurrentBagIServerStreamWriterDocumentationContentRequest _publishDocumentSubscribers;键是processId值是该进程的所有订阅者流写入器——这是典型的按进程 ID 分组的发布/订阅模型。几个关键实现点启动进程UserRequestFeatureDocumentation中若请求未携带processId则用Guid.NewGuid().ToString()生成随后DocumentGenerationProcess.CreateProcessBuilder().Build()构建进程并以process.StartAsync(new KernelProcessEvent { Id DocGenerationEvents.StartDocumentGeneration, Data new ProductInfo{...} }, processId, _actorProxyFactory)启动。注释明确说明Data传入ProductInfo是因为GatherProductInfoStep期待该类型。SK 事件回注UserReviewedDocumentation根据审批结果构造KernelProcessEvent通过则Id UserApprovedDocument, Data true拒绝则Id UserRejectedDocument, Data request.Reason再process.StartAsync(processEvent, request.ProcessData.ProcessId)让进程从对应输入事件处恢复执行。服务端流订阅RequestUserReviewDocumentation与ReceivePublishedDocumentation把responseStream加入对应订阅者集合后await context.CancellationToken.WaitHandle.ToTask()挂起直至客户端断开才在finally中用TryTake移除订阅者避免泄漏。进程内推送RequestUserReviewDocumentationFromProcess与PublishDocumentation遍历同processId的订阅者并WriteAsync实现 SK 主题到 gRPC 流的转发。gRPC ClientSK 进程的内部消息通道Clients/DocumentGenerationGrpcClient.cs 实现了 SK Process 抽象层定义的IExternalKernelProcessMessageChannel接口是进程向外部系统发事件的唯一出口。它包含三个成员Initialize()建立GrpcChannel.ForAddress(http://localhost:58641)并创建 gRPC 客户端注意58641 是 HTTP/2 端口对应下文 appsettings 配置Uninitialize()ShutdownAsync()优雅关闭通道EmitExternalEventAsync(string externalTopicEvent, KernelProcessProxyMessage message)按 SK 主题名映射到对应 gRPC 方法——RequestUserReview主题调用RequestUserReviewDocumentationFromProcessAsyncPublishDocumentation主题调用PublishDocumentationAsync均把DocumentInfo反序列化后填入Title、AssistantMessage、Content与ProcessData.ProcessId。这正是 README 所强调的核心差异SK Process 不直接感知 gRPC而是通过IExternalKernelProcessMessageChannel抽象与 Proxy Step 完成对外通信gRPC 只是该通道的一种具体实现。SK Process 与 gRPC 的事件流README 用时序图完整呈现了一次请求 → 审核 → 发布的完整交互结合 DocumentGenerationProcess.cs 中进程编排代码整个流程分六步发起gRPC 客户端调用UserRequestFeatureDocumentation服务端构建并启动 SK Process向进程发出StartDocumentGenerationSK 事件驱动GatherProductInfoStep收集产品信息。生成与审核进程执行GenerateDocumentationStep.GenerateDocs→ProofReadDocumentationStep当DocumentationApproved事件被触发时进程发出RequestUserReview主题DocumentGenerationGrpcClient将其转换为RequestUserReviewDocumentationFromProcessgRPC 方法调用服务端。注意 ProofreadDocumentationStep.cs 中该事件被标记为KernelProcessEventVisibility.Public以便持久化恢复且审核采用 OpenAI 结构化输出ResponseFormat typeof(ProofreadingResponse)保证结果可解析。通知订阅者服务端将文档写入_docReviewSubscribers中该processId对应的共享流RequestUserReviewDocumentation的订阅者随即收到待审核文档。审批回写客户端通过UserReviewedDocumentation提交documentationApproved与reason服务端将其转译为UserApprovedDocument或UserRejectedDocumentSK 事件送回进程。拒绝时会携带reason作为建议驱动GenerateDocumentationStep.ApplySuggestions重写文档后再次进入审核循环。发布审批通过后进程继续PublishDocumentationStep参数userApproval与document均已就绪执行触发PublishDocumentation主题再次经DocumentGenerationGrpcClient调用服务端对应 gRPC 方法。推送给订阅者PublishDocumentation方法更新_publishDocumentSubscribers的共享流所有订阅ReceivePublishedDocumentation的客户端都能收到最新发布的文档。进程编排层面DocGenerationEventsStartDocumentGeneration、UserRejectedDocument、UserApprovedDocument与DocGenerationTopicsRequestUserReview、PublishDocumentation分别对应外部注入进程的输入事件与进程向外发出的主题proxyStep通过AddProxyStep(id, [RequestUserReview, PublishDocumentation])注册再用.EmitExternalEvent(proxyStep, topic)挂接到具体 Step 的输出上——这正是 ProcessWithCloudEvents/README.md 中Setup一节强调的两种通信方向的落地代码。运行演示需求与启动Requirements本机已就绪Dapr环境SK Process 在 Dapr 上以 Actor 形式运行服务端依赖Dapr.Actors与Dapr.Actors.AspNetCore构建并运行应用与服务器交互有两种方式任选其一安装并运行gRPCui监听localhost:58641./grpcui.exe -plaintext localhost:58641运行 ProcessWithCloudEvents.Client 应用ReactJS gRPC Web它通过localhost:58640与服务器交互。端口差异来自 appsettings.json 的双端点配置Kestrel: { Endpoints: { Http1: { Url: http://*:58640, Protocols: Http1 }, Http2: { Url: http://*:58641, Protocols: Http2 } } }即58640 端口走 HTTP/1.1 供 gRPC Web浏览器客户端使用58641 端口走 HTTP/2 供 gRPCui 与进程内部 gRPC 客户端使用。这与 Program.cs 中AddGrpcReflection()MapGrpcReflectionService()配合 gRPCui 的服务反射、AddGrpcWeb()EnableGrpcWeb()浏览器 gRPC-Web 支持以及AllowAllCORS 策略一一对应。README 指出这遵循了官方任何 gRPC ASP.NET Core 应用的通用建议。不使用 UI 的交互方式gRPCui 三窗口操作README 给出了完整的无 UI 调试步骤。启动应用后打开 3 个 gRPCui 窗口并配置对应方法窗口 1UserRequestFeatureDocumentation与UserReviewedDocumentation窗口 2RequestUserReviewDocumentation窗口 3ReceivePublishedDocumentation所有方法统一使用同一个processId例如100然后按下述顺序执行第 1 步订阅审核流窗口 2调用RequestUserReviewDocumentation请求体{ processId: 100 }这会订阅指定processId的审核请求当进程发出通知时会收到响应。README 建议将超时设置为 30 秒。第 2 步发起文档生成窗口 1调用UserRequestFeatureDocumentation请求体{ title: some product title, userDescription: some user description, content: some product content, processId: 100 }该请求将使用该processId创建新进程并向 SK Process 注入初始事件即StartDocumentGeneration。第 3 步订阅发布流窗口 3收到RequestUserReviewDocumentation的推送后调用ReceivePublishedDocumentation{ processId: 100 }同样建议超时 30 秒等待进程发布文档时收到通知。第 4 步提交审核窗口 1调用UserReviewedDocumentation提交审核结论请求体{ documentationApproved: true, reason: , processData: { processId: 100 } }若documentationApproved为false可在reason中填写修改建议进程将携带建议触发重写后再回到审核环节若为true进程将推进到发布环节并在窗口 3 收到已发布文档。使用带 UI 的客户端应用若选择 ProcessWithCloudEvents.Client 方式先进入ProcessWithCloudEvents.Client目录执行yarn install安装依赖yarn run dev启动开发服务器后访问http://localhost:5173。其 gRPC 通信封装在 src/services/grpc/DocumentGenerationGrpcClient.ts通过protobuf-ts/grpcweb-transport以baseUrl: http://localhost:58640走 gRPC Web 协议。UI 交互逻辑位于 GenerateDocumentsChat.tsx创建文档时用uuidv4()生成新processId并订阅该进程的推送随后可一键接受或填写建议拒绝文档。调试方法README 提供了两种断点调试方式方式一Visual Studio Dapr 扩展安装 Visual Studio Dapr 扩展由扩展统一管理 Dapr sidecar 与调试器的协同启动即可在应用各个阶段设置断点README 提到仓库中提供了对应的 Dapr 配置文件供扩展读取。方式二命令行手动启动将ProcessWithCloudEvents.Grpc设为启动项目运行后附加 Visual Studio 调试器并执行dapr run --app-id processwithcloudevents-grpc --app-port 58640 --app-protocol http -- dotnet run --no-build该命令以processwithcloudevents-grpc作为 Dapr 应用 ID、58640作为应用端口启动 sidecar 与宿主进程使 SK Process 所需的 Actor 运行时见Program.cs中options.AddProcessActors()与app.MapActorsHandlers()得以在 Dapr 上运行。实现要点总结通信抽象SK Process 通过IExternalKernelProcessMessageChannel抽象与外部系统通信gRPC 仅是其中一种实现替换通道如 SignalR、HTTP、云事件等无需改动进程编排代码。方向一进程 → 外部ProxyStep接收进程内 SK 主题DocumentGenerationGrpcClient.EmitExternalEventAsync按主题映射为 gRPC 方法服务端将内容写入按processId分组的服务端流订阅者实时接收。方向二外部 → 进程外部 gRPC 调用经服务端转换为KernelProcessEvent如UserApprovedDocument/UserRejectedDocument通过process.StartAsync(event, processId)注入进程进程从对应输入事件处恢复执行。多端口设计HTTP/258641服务 gRPC 原生客户端与 gRPCuiHTTP/1.158640服务浏览器 gRPC-Web配合 gRPC 反射服务gRPCui 无需额外 schema 文件即可交互。进程可恢复性需要跨 Step 恢复的事件如DocumentationApproved传递给PublishDocumentationStep必须标记为KernelProcessEventVisibility.PublicGenerateDocumentationStep通过KernelProcessStepGenerateDocumentationState持久化对话历史与最近生成文档支撑拒绝 → 重写循环。如需进一步扩展可仿照本文的 gRPC 通道为同一DocumentGenerationProcess接入其他云事件技术仓库中的 ProcessWithCloudEvents 目录还包含其他运行时实现实现真正的进程编排与传输协议解耦。【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考