> ## Documentation Index
> Fetch the complete documentation index at: https://docs.playapi.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 图片理解

> 把图片作为对话输入，获取文字描述。

此页介绍图片输入与文字输出，不是图片生成。选择明确支持图片输入和 Chat Completions 的模型；模型列表中的 ID 本身不能证明视觉能力。

## 两种图片来源

* HTTPS 图片 URL：使用网关或上游能够直接读取的图片地址。浏览器能打开不代表服务端可访问；需要登录 Cookie、短期授权或发生跳转的地址可能失败。
* Base64 data URL：应用读取本地图片后，按实际 MIME 类型编码为 `data:image/png;base64,...` 等形式。不需要先公开托管图片，但会增加请求体大小。

不要把本地文件路径或 `file://` 地址直接当作远程图片 URL。远程访问能力、支持的格式、尺寸和数量由部署及目标模型决定。

## 可运行示例：发送本地图片

按 [Python SDK](/zh/guides/python)安装依赖并设置连接信息，然后设置额外变量：

```bash theme={null}
export API_IMAGE_PATH='/absolute/path/to/image.png'
```

用自己有权提交的图片替换路径。保存为 `vision.py` 并运行 `python vision.py`。此命令会把图片内容发往配置的 API 服务，并可能由其转发给上游。示例接受 PNG/JPEG，限制为 5 MiB；这是示例自身的限制，不代表网关或模型的额度。

```python theme={null}
import base64
import os
from pathlib import Path
from openai import OpenAI, APIConnectionError, APIStatusError

# This example's local limit is not the gateway or model's documented limit.
image_limit = 5 * 1024 * 1024
with Path(os.environ["API_IMAGE_PATH"]).open("rb") as image_file:
    image = image_file.read(image_limit + 1)
if not image or len(image) > image_limit:
    raise SystemExit("Choose a nonempty image up to 5 MiB for this example.")
if image.startswith(b"\x89PNG\r\n\x1a\n"):
    mime_type = "image/png"
elif image.startswith(b"\xff\xd8\xff"):
    mime_type = "image/jpeg"
else:
    raise SystemExit("This example accepts PNG or JPEG images only.")
image_url = f"data:{mime_type};base64,{base64.b64encode(image).decode('ascii')}"

with OpenAI(
    base_url=os.environ["API_BASE_URL"].rstrip("/"),
    api_key=os.environ["API_KEY"],
    timeout=60.0,
    max_retries=0,
) as client:
    try:
        result = client.chat.completions.create(
            model=os.environ["API_MODEL"],
            messages=[{
                "role": "user",
                "content": [
                    {"type": "text", "text": "Describe this image in one sentence."},
                    {"type": "image_url", "image_url": {"url": image_url}},
                ],
            }],
        )
        choice = result.choices[0] if result.choices else None
        if (choice is None or choice.finish_reason != "stop"
                or choice.message.refusal or choice.message.tool_calls
                or not choice.message.content):
            raise SystemExit("Image request did not produce a complete text reply.")
        print(choice.message.content)
    except APIStatusError as error:
        raise SystemExit(f"Request failed (HTTP {error.status_code}). Check the request logs.")
    except APIConnectionError:
        raise SystemExit("Connection failed. Check the API address and network.")
```

本例通过文件头选择 MIME，不负责验证图片是否完整可解码。实际服务还可能限制像素、编码和总请求大小；Base64 后的负载比原文件更大。不要在日志中保存整段 data URL。

## 两种协议的字段

| 项目 | Chat Completions | Responses |
| - | - | - |
| 文本块 | `type: text`，文本放 `text` | `type: input_text`，文本放 `text` |
| 图片块 | `type: image_url`，`image_url` 是含 `url` 的对象 | `type: input_image`，`image_url` 是字符串 |

需要切换到 Responses 时，应同时调整输入项结构。`detail` 等可选参数需模型支持，先验证不带额外参数的请求。

## Python：Responses 图片理解

保存为 `responses-vision.py`，沿用上方 Python 环境与 `API_IMAGE_PATH`，运行 `python responses-vision.py`。这会提交图片到配置的服务；选择支持 Responses 图片输入的模型与渠道。示例使用同样的 5 MiB 本地文件上限，明确区分 `input_text` 和 `input_image`，不需要先上传到 Files API。

```python theme={null}
import base64
import os
from pathlib import Path
from openai import OpenAI, APIConnectionError, APIStatusError

# This example's local limit is not the gateway or model's documented limit.
image_limit = 5 * 1024 * 1024
with Path(os.environ["API_IMAGE_PATH"]).open("rb") as image_file:
    image = image_file.read(image_limit + 1)
if not image or len(image) > image_limit:
    raise SystemExit("Choose a nonempty image up to 5 MiB for this example.")
if image.startswith(b"\x89PNG\r\n\x1a\n"):
    mime_type = "image/png"
elif image.startswith(b"\xff\xd8\xff"):
    mime_type = "image/jpeg"
else:
    raise SystemExit("This example accepts PNG or JPEG images only.")
image_url = f"data:{mime_type};base64,{base64.b64encode(image).decode('ascii')}"

with OpenAI(
    base_url=os.environ["API_BASE_URL"].rstrip("/"),
    api_key=os.environ["API_KEY"],
    timeout=60.0,
    max_retries=0,
) as client:
    try:
        result = client.responses.create(
            model=os.environ["API_MODEL"],
            input=[{
                "role": "user",
                "content": [
                    {"type": "input_text", "text": "Describe this image in one sentence."},
                    {"type": "input_image", "image_url": image_url},
                ],
            }],
        )
        if result.status != "completed" or not result.output_text.strip():
            raise SystemExit("Image request did not produce a complete text reply.")
        for item in result.output:
            if item.type == "reasoning":
                continue
            if (item.type != "message" or item.status != "completed"
                    or any(part.type != "output_text" for part in item.content)):
                raise SystemExit("Image request did not produce a complete text reply.")
        print(result.output_text)
    except APIStatusError as error:
        raise SystemExit(f"Request failed (HTTP {error.status_code}). Check the request logs.")
    except APIConnectionError:
        raise SystemExit("Connection failed. Check the API address and network.")
```

与 Chat 示例一样，文件头检查不等于完整图片解码。响应必须已完成且包含非空文本；拒答、未完成消息和工具项不会作为识别结果输出。

## 常见问题

| 现象 | 排查方向 |
| - | - |
| 拒绝内容类型或参数 | 确认模型视觉能力、接口协议与渠道转换支持 |
| 无法读取 URL | 检查服务端可达性、授权、链接有效期和图片内容类型 |
| 413 或请求过大 | 检查反向代理、网关及上游限制；在应用中合理压缩或缩小图片 |
| 空文本或截断 | 检查完成原因、拒答信息与目标模型的返回格式 |
| 识别不准确 | 检查图像清晰度、文字尺寸及问题是否明确，必要时人工核对 |

[HTTP 接入](/zh/guides/http) · [错误与重试](/zh/guides/errors)

参考：[OpenAI 图片输入说明](https://developers.openai.com/api/docs/guides/images-vision)。

[需要生成或编辑图片？阅读图片生成指南](/zh/guides/image-generation)。

[Read in English](/en/guides/vision)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.