Rust中serde_json反序列化失败:expected value at line 1 column 1
问题分析与解决方案:serde_json反序列化LLM响应失败
问题根源
你遇到的expected value at line 1 column 1错误,本质是LLM返回的内容不是合法JSON格式。从打印的响应内容build a fullstack website with user login and logout可以看到,这是纯自然语言文本,不符合JSON的语法规则(比如字符串需要用双引号包裹,对象/数组有特定结构),而serde_json::from_str仅能解析标准JSON数据,因此反序列化必然失败。
解决方案
方案1:强制LLM返回标准JSON格式
修改调用LLM的提示词,明确要求返回严格的JSON结构。例如在context中添加类似约束:
请将你的回答以严格的JSON格式返回,示例格式:{"result": "你的具体回答内容"}
之后可以定义对应结构体来接收数据:
use serde::Deserialize; #[derive(Deserialize)] struct LlmResponse { result: String, } // 调用ai_request时指定T为LlmResponse let response: LlmResponse = ai_request(context, "user").await;
方案2:适配纯文本响应(无法修改LLM输出时)
如果无法调整LLM的输出格式,可直接将T指定为String,跳过JSON反序列化步骤,或者手动将纯文本包装成合法JSON后再解析:
// 直接返回字符串类型 pub async fn ai_request(context: String, position: &str) -> String { let llm_response: String = ai_task(context, position).await; eprintln!("llm_response {}", &llm_response); llm_response } // 或者手动包装为JSON后反序列化到结构体 pub async fn ai_request<T: DeserializeOwned>(context: String, position: &str) -> T { let llm_response: String = ai_task(context, position).await; eprintln!("llm_response {}", &llm_response); // 将纯文本包装为JSON字符串字面量,转义内部双引号 let json_wrapped = format!("\"{}\"", llm_response.replace('"', "\\\"")); let decoded_response: Result<T, _> = serde_json::from_str(&json_wrapped); match decoded_response { Ok(response) => response, Err(err) => { eprintln!("Failed to decode ai response from serde_json: {}", err); panic!("Failed to process LLM response"); // 替换临时占位符的合理错误处理 } } }
调试技巧
- 手动验证JSON合法性:将LLM返回的内容复制后,检查是否符合JSON语法(比如字符串是否有双引号包裹、结构是否正确)
- 添加前置格式检查:在反序列化前,可使用
serde_json::from_str::<serde_json::Value>做预校验,判断输入是否为合法JSON,再进行后续处理:
match serde_json::from_str::<serde_json::Value>(&llm_response) { Ok(_) => { /* 继续反序列化为目标类型 */ } Err(e) => { /* 处理非JSON格式的响应 */ } }
内容的提问来源于stack exchange,提问作者Yilmaz
相关产品推荐
相关产品推荐

