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

发布时间:2026/9/12 3:59:43

基于 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/9/12 3:59:43

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

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

2026/9/12 3:54:43

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

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

2026/9/12 4:34:47

Java StringEntry接口设计与实现最佳实践

1. StringEntry接口的设计背景与核心诉求在软件开发中,数据结构的抽象与封装一直是提升代码复用性和可维护性的关键手段。StringEntry这个接口概念的提出,本质上是为了解决字符串类型数据在多种场景下的统一操作问题。我最近在重构一个历史遗留系统时&am…

2026/9/12 4:34:47

海光DCU接入K8s:整卡、共享与vDCU调度实战解析

如果你接过“把一批海光 DCU 节点接进 Kubernetes,再让上层 AI 平台和 DeepSeek 推理服务跑起来”这种需求,第一反应大概率是:装个驱动、部署个 Device Plugin 不就行了?真动手之后才会发现,整卡、共享、vDCU 虚拟化是…

2026/9/12 4:34:47

2026年软考高级系统分析师论文备考指南与高分技巧

1. 2026年软考高级系统分析师论文备考指南作为国内IT领域最具含金量的职业资格认证之一,软考高级系统分析师(以下简称"系分")的论文环节一直是考生面临的"拦路虎"。不同于选择题和案例分析,论文写作不仅需要扎…

2026/9/12 4:34:47

Linux下TFTP服务器安装配置与优化指南

1. Linux下TFTP服务器的安装与配置指南在嵌入式开发和网络设备维护领域,TFTP(Trivial File Transfer Protocol)作为轻量级文件传输协议,因其实现简单、资源占用少的特点,成为固件更新、配置文件传输的标配工具。不同于…

2026/9/12 4:34:47

ThinkPHP在线客服系统实战:多坐席分配与部署调优全解析

简介:基于ThinkPHP框架打造的运营级在线客服系统源码,面向需要快速搭建网页客服、多坐席协作与智能客服平台的开发者和企业技术团队,可直接用于电商、官网、SaaS产品等场景的客户服务模块。系统包含实时聊天、坐席状态管理、访客分配、智能自…

2026/9/12 4:29:47

PyMC 采样与推断方法实战指南:MCMC、变分推断与诊断调优

PyMC 采样与推断方法实战指南:MCMC、变分推断与诊断调优 【免费下载链接】scientific-agent-skills Turn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000 scientists worldwide. 165 ready-to-use validated skills…

2026/9/12 2:05:33

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/12 3:55:12

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/9 16:31:09

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/12 0:04:17

MATLAB仿生优化框架:长鼻浣熊算法多策略融合实现

简介:本资源是一份面向智能优化算法研究者与MATLAB初学者的仿生智能算法实践代码包,聚焦于长鼻浣熊优化算法(COA)的多策略改进与性能验证。针对传统COA易陷局部最优、收敛精度不足等问题,作者融合Circle映射初始化提升…

2026/9/12 0:04:17

【JAVA毕设源码分享】基于 JavaWeb 的校园一卡通管理系统的设计与实现 基于 JavaWeb 的校园卡业务管理系统(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/9/12 0:04:17

【JAVA毕设源码分享】基于 Java 的图书馆借阅管理平台的搭建与实现 基于 Java 的图书馆综合管理系统(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/9/10 12:32:02

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/10 15:19:50

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/10 15:49:53

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

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

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

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