# json.decoder.JSONDecodeError: 期望属性名称用双引号括起来：在解析流式函数调用参数时，第 1 行第 1024 列（字符 1023）

- **ID:** `llm/function-call-arguments-truncated-in-streaming`
- **领域:** llm
- **类别:** protocol_error
- **验证级别:** ai_generated
- **修复率:** 85%

## 根因

当流式传输函数调用时，API 会分块发送参数。如果参数字符串很长，块边界可能会分割 JSON 令牌（例如，字符串值或键），导致在增量解析时累积的参数成为无效 JSON。

## 版本兼容性

| 版本 | 状态 | 引入 | 弃用 |
|------|------|------|------|
| openai==1.30.0 | active | — | — |
| anthropic==0.25.0 | active | — | — |
| mistralai==0.1.0 | active | — | — |

## 解决方案

1. ```
   在尝试解析之前，累积函数调用的所有块。等待 'finish_reason' 为 'stop' 或 'function_call' 后再解析完整的参数字符串。示例：

full_args = ""
for chunk in stream:
    delta = chunk.choices[0].delta
    if delta.function_call and delta.function_call.arguments:
        full_args += delta.function_call.arguments
    if chunk.choices[0].finish_reason:
        break
import json
parsed_args = json.loads(full_args)
   ```
2. ```
   使用 '增量解析' 方法，配合 JSON 修复库（如 'json-repair' 或 'json5'）处理部分 JSON。示例：

import json5
partial_args = ""
for chunk in stream:
    delta = chunk.choices[0].delta
    if delta.function_call and delta.function_call.arguments:
        partial_args += delta.function_call.arguments
        try:
            parsed = json5.loads(partial_args)
            # 增量使用解析结果
        except Exception:
            pass
   ```
3. ```
   设置 API 参数 'stream_options' 为 {'include_usage': True}，并使用 'usage' 字段检测函数调用参数的结束，然后解析完整字符串。
   ```

## 无效尝试

- **Using json.loads() on each individual chunk instead of accumulating** — Individual chunks are not valid JSON; they are partial fragments. json.loads() will always fail on incomplete chunks. (95% 失败率)
- **Increasing max_tokens to reduce chunking** — max_tokens controls the output length, not the chunk size. The API still sends chunks of arbitrary size regardless of max_tokens. (80% 失败率)
- **Setting stream_options={'include_usage': True}** — This option controls whether usage information is included in the stream, it has no effect on how function call arguments are chunked or parsed. (90% 失败率)
