ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Semantic Kernel 如何用 Filter 调用质量指标服务校验 LLM 生成结果

Semantic Kernel 如何用 Filter 调用质量指标服务校验 LLM 生成结果 Semantic Kernel 如何用 Filter 调用质量指标服务校验 LLM 生成结果【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel对文本摘要、翻译这类任务LLM 的生成结果质量不稳定直接信任有风险。Semantic Kernel 的 QualityCheck 示例给出了一个可落地的做法注册一个 Function Invocation Filter在函数调用完成后把原始文本和 LLM 生成结果发往一个独立的 Python 质量指标服务当指标得分低于配置的阈值时抛出KernelException使本次调用以失败结束。整个环境由两部分组成一个 .NET 的 Semantic Kernel 应用加上一个基于 Python 3.12 的 FastAPI 评估服务需要 Hugging Face API token并且已在 Hugging Face 门户接受Unbabel/wmt22-cometkiwi-da模型的使用条款。示例涉及的四种指标及其对应关系如下端点来自 python-server/app/main.py指标服务端端点适用任务与阈值比较的字段BERTScore/bert-score/摘要F1BLEU/bleu-score/摘要precisions[0]METEOR/meteor-score/摘要scoreCOMET/comet-score/翻译scores[0]其中 BERTScore、BLEU、METEOR 用于摘要任务COMET 用于翻译任务各指标的具体计算由 Hugging Face Evaluate 库在服务端完成。启动质量指标服务按 QualityCheck README 的说明前置条件有三项Python 3.12一个 Hugging Face API token已在 Hugging Face 门户接受Unbabel/wmt22-cometkiwi-da模型的访问条件COMET 端点依赖该模型。主路径直接运行 Python 服务进入示例中的python-server目录dotnet/samples/Demos/QualityCheck/python-server创建并激活虚拟环境cd python-server python -m venv venv source venv/Scripts/activate # activate on Windows source venv/bin/activate # activate on Unix/MacOS配置 Hugging Face 登录your_token替换为你自己的 Hugging Face API tokenpip install huggingface_hub[cli] huggingface-cli login --token your_token安装依赖requirements.txt 包含fastapi、uvicorn、pydantic、bert_score、nltk、evaluate、cmake、unbabel-cometpip install -r requirements.txt启动服务cd app uvicorn main:app --port 8080 --reload服务监听在http://localhost:8080。README 给出的验证方式是打开http://localhost:8080/docs查看可用的端点应能看到上表中的四个 POST 端点。可选分支用 Docker 运行如果不想在本机建 Python 环境README 提供了 Docker 方式在python-server目录下创建如下的Dockerfile构建过程会执行pip install和huggingface-cli login需要网络访问token 通过 Docker secret 传入不会写进镜像# syntaxdocker/dockerfile:1.2 FROM python:3.12 WORKDIR /code COPY ./requirements.txt /code/requirements.txt RUN pip install huggingface_hub[cli] RUN --mounttypesecret,idhf_token \ huggingface-cli login --token $(cat /run/secrets/hf_token) RUN pip install cmake RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt COPY ./app /code/app CMD [fastapi, run, app/main.py, --port, 80]创建.env/hf_token.txt文件并把 Hugging Face API token 写入其中docker-compose.yml 通过secrets引用该文件然后构建并运行容器docker-compose up --builddocker-compose.yml将容器 80 端口映射到宿主机的 8080 端口所以服务地址同样是http://localhost:8080验证方式与直接运行一致打开http://localhost:8080/docs查看端点。在 SK 应用中注册 Filter确认评估服务可用后配置 .NET 侧。QualityCheckWithFilters/Program.cs 中的GetKernelBuilder方法展示了完整的注册代码scoreType为EvaluationScoreType的某个值threshold是本次运行使用的阈值// Create kernel builder var builder Kernel.CreateBuilder(); // Add logging builder.Services.AddLogging(loggingBuilder loggingBuilder.AddConsole().SetMinimumLevel(LogLevel.Information)); // Add default HTTP client with base address to local evaluation server builder.Services.AddHttpClient(default, client { client.BaseAddress new Uri(http://localhost:8080); }); // Add service which performs HTTP requests to evaluation server builder.Services.AddSingletonEvaluationService( sp new EvaluationService( sp.GetRequiredServiceIHttpClientFactory().CreateClient(default), scoreType.Endpoint)); // Add function invocation filter to perform evaluation and compare metric score with configured threshold builder.Services.AddSingletonIFunctionInvocationFilter( sp FilterFactory.Create( scoreType, sp.GetRequiredServiceEvaluationService(), sp.GetRequiredServiceILoggerProgram(), threshold));各部分的职责AddHttpClient注册的default客户端以http://localhost:8080为基地址即指向刚启动的评估服务EvaluationService负责向评估服务发 HTTP POST 请求第二个构造参数是端点路径如bert-score见 Models/EvaluationScoreType.csBERT、BLEU、METEOR、COMET四个值各自绑定一个端点名IFunctionInvocationFilter由 Filters/FilterFactory.cs 按scoreType选出对应的 Filter 实现阈值作为参数传入。以 BERT FilterFilters/BertSummarizationEvaluationFilter.cs为例它在OnFunctionInvocationAsync中先执行await next(context)让函数正常完成然后var sourceText context.Result.RenderedPrompt!; var summary context.Result.ToString();也就是说 Filter 以渲染后的 Prompt 作为源文本、以函数结果作为待评估文本把两者装入请求发给评估服务用结构化日志输出得分最后比较分数if (f1 threshold) { throw new KernelException($BERT summary evaluation score ({f1}) is lower than threshold ({threshold})); }这是“调用后校验”LLM 结果已经产生Filter 再决定放行还是以异常中断。注意四个 Filter 各自比较的字段并不相同见开头表格例如 BLEU Filter 比较的是precisions[0]而不是返回的Score。示例用FakeChatCompletionServiceServices/FakeChatCompletionService.cs模拟 LLM 返回固定文本builder.Services.AddSingletonIChatCompletionService(new FakeChatCompletionService(extractive-summary-model, ExtractiveSummary));Program.cs 中的注释说明摘要任务用哪个 LLM 并不重要示例重点在于演示如何评估结果并比较指标因此才用 Fake 服务预置生成内容。评估逻辑本身与具体模型无关。运行并核对校验结果README 的 Testing 一节给出的运行方式是打开并运行QualityCheckWithFilters/Program.cs即可实验不同的评估指标、阈值和输入参数。Main方法依次跑四组评估每组通过不同ModelId的假服务产生“抽取式摘要 / 生成式摘要 / 随机文本”翻译组为三条不同的译文每调用一次就触发一次 Filter 校验await kernel.InvokePromptAsync(input, new(new PromptExecutionSettings { ModelId modelId }));四组评估在示例中使用的阈值分别是BERT 为 0.85、BLEU 为 0.5、METEOR 为 0.1、COMET 为 0.4。InvokeAsync捕获KernelException并用日志输出Program.cs 注释中记录的 BERT 组输出如下文档示例不同环境下的分数会有差异Extractive summary: [BERT] Precision: 0.9756, Recall: 0.9114, F1: 0.9424 Abstractive summary: [BERT] Precision: 0.8953, Recall: 0.8656, F1: 0.8802 Random summary: [BERT] Precision: 0.8433, Recall: 0.787, F1: 0.8142 Exception occurred during function invocation: BERT summary evaluation score (0.8142) is lower than threshold (0.85)核对方式就是看这两类日志每次调用都会输出一行[指标名]开头的得分日志当得分低于阈值时Filter 抛出的KernelException会被记录为Exception occurred during function invocation: ... is lower than threshold (...)。示例中“Random summary / random translation”是与原文无关的对照文本其得分低于阈值、触发异常正是示例设计的预期行为。翻译组的示例输出文档示例Text to translate: Berlin ist die Hauptstadt der Deutschland. Translation: Berlin is the capital of Germany - [COMET] Score: 0.8695 Translation: Berlin capital Germany is of The - [COMET] Score: 0.4724 Translation: This is random translation - [COMET] Score: 0.3525 Exception occurred during function invocation: COMET translation evaluation score (0.3525) is lower than threshold (0.4)边界与限制阈值是每场景配置的示例中阈值作为参数传入GetKernelBuilder每次构建 Kernel 时确定不是全局设置换指标或换阈值意味着重新构建并注册对应 Filter。BLEU 的比较字段是precisions[0]与上面日志中BLEU summary evaluation score (0.2)一致该值是precisions数组首元素不是Score示例输出中Score: 0。写断言或告警时要以 Filter 实际比较的字段为准。COMET 端点依赖远端模型main.py 中comet_score端点会执行download_model(Unbabel/wmt22-cometkiwi-da)所以 Hugging Face token 和模型访问权限是翻译评估的前置条件缺少时该端点不可用。源文本取自RenderedPromptFilter 将渲染后的 Prompt 视为参照文本。示例中直接输入的就是待摘要/待翻译原文如果你的 Prompt 里混有指令文字参照文本也会包含这些内容这一点需要根据自己场景判断。示例输入是固定的摘要组与翻译组都使用代码中内置的固定文本和固定生成结果目的是演示指标对比与阈值拦截而不是覆盖真实业务输入。以上路径对应的完整文件都在 dotnet/samples/Demos/QualityCheck 目录下可按 README 顺序复现。【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进