尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

【Bug已解决】`BedrockService.GetStreamingResponseAsync` returns…

【Bug已解决】`BedrockService.GetStreamingResponseAsync` returns… 【Bug已解决】BedrockService.GetStreamingResponseAsyncreturns Amazon.BedrockRuntime.Model.ValidationException 解决方案一、现象长什么样你在 .NET 里用 AWS SDK 的BedrockService.GetStreamingResponseAsync即AmazonBedrockRuntimeClient的流式调用请求 Claude抛Amazon.BedrockRuntime.Model.ValidationException或流还没开始就被校验拒绝你用InvokeModelWithResponseStreamAsync/GetStreamingResponseAsync包装了请求但 body 不合规报错比同步InvokeModel更难读因为流式请求的 body 结构和字段名仍有要求你确认模型 ID 对、key 对但流式就是 ValidationException你怀疑流式 API 和同步 API 的请求格式不同。一句话GetStreamingResponseAsync底层仍是 Bedrock 的流式推理请求body 必须符合 Claude on Bedrock 的格式契约顶层anthropic_version、正确的max_tokens层级、system数组、content 块结构。你构造的流式请求 body 某处不合规于是被ValidationException拒绝。二、背景AWS SDK for .NET 里AmazonBedrockRuntimeClient提供InvokeModelAsync同步整段响应InvokeModelWithResponseStreamAsync/ 经BedrockService封装的GetStreamingResponseAsync流式逐块Chunk。两者都要求请求 body 符合模型格式。对 Claude on Bedrock流式 body 与同步 body 格式一致都是那段 JSON只是响应以流形式返回。所以流式报 ValidationException和同步报 malformed根因相同——都是 body 字段不对见 934。常见流式专属坑用InferenceConfig但字段名错MaxTokens大小写、或放在错误层级流式的RequestStream里塞了非 JSON 或编码错误ModelId在流式调用时用了简写同 936 问题。三、根因根因是流式请求的 body 不符合 Claude on Bedrock 格式// 错误流式 body 里 system 是字符串、缺 anthropic_version var request new InvokeModelWithResponseStreamRequest { ModelId anthropic.claude-3-5-sonnet-20241022-v2:0, Body new MemoryStream(Encoding.UTF8.GetBytes(JsonSerializer.Serialize(new { max_tokens 256, system 你是助手, // 应为 [{text:...}] messages new[] { new { roleuser, contentnew[]{new{texthi}} } } }))) }; // - ValidationException// 正确 var body new { anthropic_version bedrock-2023-05-31, max_tokens 256, system new[] { new { text 你是助手 } }, messages new[] { new { roleuser, contentnew[]{new{texthi}} } } };四、最小可运行复现下面用 C# 伪代码演示流式请求 body 校验using Amazon.BedrockRuntime; using Amazon.BedrockRuntime.Model; var client new AmazonBedrockRuntimeClient(region: RegionEndpoint.USWest2); var body new { anthropic_version bedrock-2023-05-31, max_tokens 256, system new[] { new { text 你是助手 } }, messages new[] { new { role user, content new[] { new { text 你好 } } } } }; var req new InvokeModelWithResponseStreamRequest { ModelId anthropic.claude-3-5-sonnet-20241022-v2:0, ContentType application/json, Accept application/json, Body new MemoryStream(System.Text.Encoding.UTF8.GetBytes( System.Text.Json.JsonSerializer.Serialize(body))) }; // 逐块读流式响应 var resp await client.InvokeModelWithResponseStreamAsync(req); await foreach (var chunk in resp.Body) { // chunk.Bytes 是 SSE/JSON 片段 Console.Write(System.Text.Encoding.UTF8.GetString(chunk.Bytes.ToArray())); }若body里system是字符串或漏anthropic_versionInvokeModelWithResponseStreamAsync直接抛ValidationException。五、解决方案第一层最小直接修复最小修复是构造合规的流式 body顶层anthropic_versionsystem数组 正确max_tokensvar body new { anthropic_version bedrock-2023-05-31, max_tokens 256, system new[] { new { text 你是助手 } }, messages new[] { new { role user, content new[] { new { text 你好 } } } } }; var req new InvokeModelWithResponseStreamRequest { ModelId anthropic.claude-3-5-sonnet-20241022-v2:0, ContentType application/json, Accept application/json, Body new MemoryStream(JsonSerializer.SerializeToUtf8Bytes(body)), }; using var resp await client.InvokeModelWithResponseStreamAsync(req); await foreach (var chunk in resp.Body) { // 解析 chunk 里的 delta.text 并输出参考 940 的 SignalR 推送 }要点流式不改变 body 格式要求system必须是数组、anthropic_version必填。六、解决方案第二层结构化改进把流式请求 body 校验做成策略提交前自检避免ValidationExceptionfrom dataclasses import dataclass, field from typing import Any, Dict, List dataclass(frozenTrue) class BedrockStreamingValidationPolicy: Bedrock 流式请求策略消灭 ValidationException。 规则 - anthropic_version 必填 - system 必须是文本块数组 - max_tokens 为合法正数 - messages content 为块数组 def build(self, *, model_id: str, system: str, messages: List[Dict], max_tokens: int 256) - Dict: if not model_id or anthropic.claude not in model_id: raise ValueError(model_id 必须是完整 Bedrock identifier) if not isinstance(system, str) or len(system) 0: raise ValueError(system 不能为空) if not messages: raise ValueError(messages 不能为空) if not (1 max_tokens 8192): raise ValueError(max_tokens 必须 1~8192) return { anthropic_version: bedrock-2023-05-31, max_tokens: max_tokens, system: [{text: system}], messages: messages, } def demo() - None: policy BedrockStreamingValidationPolicy() b policy.build( model_idanthropic.claude-3-5-sonnet-20241022-v2:0, system你是助手, messages[{role: user, content: [{text: hi}]}], ) assert b[anthropic_version] bedrock-2023-05-31 print(流式 body 合规) if __name__ __main__: demo()七、解决方案第三层断言 / CI 守护import pytest from your_module import BedrockStreamingValidationPolicy def test_build_ok(): policy BedrockStreamingValidationPolicy() b policy.build(model_idanthropic.claude-x:0, systems, messages[{role: user, content: [{text: y}]}]) assert b[system] [{text: s}] def test_missing_version_in_body(): # 策略在 body 内置版本但 model_id 仍需校验 policy BedrockStreamingValidationPolicy() with pytest.raises(ValueError): policy.build(model_idclaude-x, systems, messages[{role: user, content: [{text: y}]}]) def test_empty_system(): policy BedrockStreamingValidationPolicy() with pytest.raises(ValueError): policy.build(model_idanthropic.claude-x:0, system, messages[{role:user,content:[{text:y}]}]) def test_bad_max_tokens(): policy BedrockStreamingValidationPolicy() with pytest.raises(ValueError): policy.build(model_idanthropic.claude-x:0, systems, messages[{role:user,content:[{text:y}]}], max_tokens0) def test_empty_messages(): policy BedrockStreamingValidationPolicy() with pytest.raises(ValueError): policy.build(model_idanthropic.claude-x:0, systems, messages[]) def test_version_present(): policy BedrockStreamingValidationPolicy() b policy.build(model_idanthropic.claude-x:0, systems, messages[{role:user,content:[{text:y}]}]) assert b[anthropic_version] bedrock-2023-05-31CI 里加一条在调用GetStreamingResponseAsync前跑build自检确保 body 合规再发流避免ValidationException。八、排查清单流式 body 是否带了anthropic_version: bedrock-2023-05-31system是否文本块数组非字符串max_tokens是否合法正数、层级正确ModelId是否完整 Bedrock identifier非简写流式响应是否逐块解析chunk.Bytes别把整段当同步处理。是否混淆了同步InvokeModel与流式InvokeModelWithResponseStreamAsync的 body其实格式一致九、小结BedrockService.GetStreamingResponseAsync抛ValidationException根因是流式请求 body 不符合 Claude on Bedrock 格式顶层anthropic_version、system数组、max_tokens合法、content 块数组与同步调用同源。最小修复是构造合规的流式 body系统数组化、补全版本、完整 model ID再发流结构化做法是抽成BedrockStreamingValidationPolicy提交前自检最后用 pytest 守护body 合规才可发流杜绝 ValidationException。
返回列表