# Phad LLM SDK for Python

Phad LLM SDK 是一个用于与大语言模型交互的 Python SDK，提供了统一的调用接口，支持流式响应和非流式响应，简化了大模型服务的调用流程。同时支持多模态大模型，可以处理包含图片和文本的复杂请求。

## 功能特性

### LLMClient 功能
- **统一调用接口**：提供了简洁易用的 API，支持多种大语言模型服务
- **流式响应支持**：支持流式返回生成结果，提升用户体验
- **消息构建器**：内置消息构建器，方便构建对话消息列表
- **单例模式**：客户端采用单例模式，确保资源高效利用
- **环境变量配置**：通过环境变量灵活配置服务地址和路径
- **思考过程**：支持返回模型的思考过程

### VLLMClient 功能
- **多模态支持**：支持处理包含图片和文本的复杂请求
- **图片分析**：可以分析图片内容并生成描述
- **流式响应**：支持多模态内容的流式返回
- **灵活的消息构建**：支持文本、图片等多种消息类型组合

## 安装

### 从 PyPI 安装

```bash
pip install phad-llm-sdk
```

### 从源码安装

```bash
# 克隆仓库
git clone https://github.com/yourusername/phad-llm-sdk-python.git
cd phad-llm-sdk-python

# 安装包
pip install -e .
```

## 配置

SDK 需要通过环境变量配置以下参数：

### LLMClient 配置
- `VLLM_LLM_URL`: 大模型服务的基础 URL
- `LLM_QWEN_PATH`: API 路径（可选）

### VLLMClient 配置
- `VLLM_VLLM_URL`: 多模态大模型服务的基础 URL
- `VLLM_QWEN_PATH`: API 路径（可选）

你可以创建一个 `.env` 文件来存储这些配置：

```
# LLMClient 配置
VLLM_LLM_URL=http://localhost:8000
LLM_QWEN_PATH=v1/chat/completions

# VLLMClient 配置
VLLM_VLLM_URL=http://localhost:8000
VLLM_QWEN_PATH=v1/chat/completions
```

## 快速开始

### LLMClient 使用

#### 基本使用

```python
from phad_llm_sdk import llm_client

# 使用消息构建器构建消息列表
message_builder = llm_client.create_message_builder()
messages = message_builder\
    .add_system_message("你是一个AI助手，喜欢帮助别人。")\
    .add_user_message("你好，能帮我解释一下什么是机器学习吗？")\
    .build()

# 调用大模型（非流式）
response = llm_client.chat(messages)
print("非流式响应:")
print(response)

# 调用大模型（流式）
print("\n流式响应:")
stream_response = llm_client.chat(messages, stream=True)
if stream_response:
    import json
    for chunk in stream_response.iter_lines():
        if chunk:
            chunk = chunk.decode('utf-8')
            if chunk.startswith('data: '):
                chunk = chunk[6:]
            if chunk == '[DONE]':
                break
            try:
                chunk_data = json.loads(chunk)
                content = chunk_data.get("choices", [{}])[0].get("delta", {}).get("content", "")
                if content:
                    print(content, end="")
            except json.JSONDecodeError:
                pass
    print()
else:
    print("流式请求失败")
```

#### 自定义参数

```python
from phad_llm_sdk import llm_client

# 构建消息
message_builder = llm_client.create_message_builder()
messages = message_builder\
    .add_system_message("你是一个AI助手，喜欢帮助别人。")\
    .add_user_message("你好，能帮我解释一下什么是深度学习吗？")\
    .build()

# 自定义参数调用
response = llm_client.chat(
    messages=messages,
    stream=False,
    max_tokens=500,
    temperature=0.8,
    top_p=0.9,
    think=True
)
print(response)
```

### VLLMClient 使用

#### 多模态图片分析

```python
from phad_llm_sdk.client.VLLMClient import vllm_client

# 创建消息构建器
message_builder = vllm_client.create_message_builder()

# 构建多模态消息（图片 + 文本）
messages = message_builder\
    .add_image_message(
        "https://picsum.photos/id/10/800/600", 
        "请详细描述这张图片的内容，包括场景、颜色、物体等"
    )\
    .build()

# 调用多模态大模型（非流式）
response = vllm_client.chat(messages)
print("非流式响应:")
print(response)
```

#### 流式多模态响应

```python
from phad_llm_sdk.client.VLLMClient import vllm_client
import json

# 创建消息构建器
stream_message_builder = vllm_client.create_message_builder()

# 构建多模态消息
stream_messages = stream_message_builder\
    .add_image_message(
        "https://picsum.photos/id/20/800/600", 
        "这张图片中有什么物体？请详细描述。"
    )\
    .build()

# 流式调用
stream_response = vllm_client.chat(stream_messages, stream=True)
if stream_response:
    print("流式响应:")
    for chunk in stream_response.iter_lines():
        if chunk:
            chunk = chunk.decode('utf-8')
            if chunk.startswith('data: '):
                chunk = chunk[6:]
            if chunk == '[DONE]':
                break
            try:
                chunk_data = json.loads(chunk)
                content = chunk_data.get("choices", [{}])[0].get("delta", {}).get("content", "")
                if content:
                    print(content, end="")
            except json.JSONDecodeError:
                pass
    print()
else:
    print("流式请求失败")
```

#### 多轮对话示例

```python
from phad_llm_sdk.client.VLLMClient import vllm_client

# 创建消息构建器
message_builder = vllm_client.create_message_builder()

# 构建多轮对话
messages = message_builder\
    .add_system_message("你是一个专业的图片分析师")\
    .add_user_message("https://picsum.photos/id/10/800/600", "请描述这张图片")\
    .add_assistant_message("这张图片展示了一个森林场景...")\
    .add_user_message("图片中的主要颜色是什么？")\
    .build()

# 调用大模型
response = vllm_client.chat(messages)
print(response)
```

## API 文档

### LLMClient

`LLMClient` 是大模型客户端的主类，提供了与大语言模型交互的核心方法。

#### 方法

- `chat(messages, stream=False, max_tokens=200, temperature=0.7, top_p=0.1, think=False)`: 调用大模型进行对话
  - `messages`: 消息列表，格式为 `[{"role": "system", "content": "..."}, {"role": "user", "content": "..."}]`
  - `stream`: 是否使用流式响应
  - `max_tokens`: 最大生成 token 数
  - `temperature`: 温度参数，控制生成的随机性
  - `top_p`: 采样的核概率，控制生成的多样性
  - `think`: 是否返回思考过程
  - 返回值: 如果 `stream=True`，返回响应对象；如果 `stream=False`，返回 `{"message": {"content": "回答内容"}}`

- `create_message_builder()`: 创建消息构建器
  - 返回值: `MessageBuilder` 实例

### MessageBuilder

`MessageBuilder` 是一个消息构建器，用于方便地构建消息列表。

#### 方法

- `add_message(role, content)`: 添加一条消息
  - `role`: 角色，例如 "system"、"user"、"assistant"
  - `content`: 消息内容
  - 返回值: 自身，支持链式调用

- `add_system_message(content)`: 添加系统消息
  - `content`: 系统消息内容
  - 返回值: 自身，支持链式调用

- `add_user_message(content)`: 添加用户消息
  - `content`: 用户消息内容
  - 返回值: 自身，支持链式调用

- `add_assistant_message(content)`: 添加助手消息
  - `content`: 助手消息内容
  - 返回值: 自身，支持链式调用

- `build()`: 构建消息列表
  - 返回值: 消息列表，格式为 `[{"role": "...", "content": "..."}]`

### VLLMClient

`VLLMClient` 是多模态大模型客户端的主类，提供了与多模态大语言模型交互的核心方法，支持图片和文本的混合输入。

#### 方法

- `chat(messages, stream=False, max_tokens=1024, temperature=0.7)`: 调用多模态大模型进行对话
  - `messages`: 消息列表，格式为 `[{"role": "user", "content": [{"type": "image_url", "image_url": {"url": "..."}}, {"type": "text", "text": "..."}]}]`
  - `stream`: 是否使用流式响应
  - `max_tokens`: 最大生成 token 数
  - `temperature`: 温度参数，控制生成的随机性
  - 返回值: 如果 `stream=True`，返回响应对象；如果 `stream=False`，返回 `{"message": {"content": "回答内容"}}`

- `create_message_builder()`: 创建多模态消息构建器
  - 返回值: `MultiModalMessageBuilder` 实例

### MultiModalMessageBuilder

`MultiModalMessageBuilder` 是一个多模态消息构建器，用于方便地构建包含图片和文本的消息列表。

#### 方法

- `add_message(role, content)`: 添加一条消息
  - `role`: 角色，例如 "system"、"user"、"assistant"
  - `content`: 消息内容，可以是字符串或包含图片和文本的列表
  - 返回值: 自身，支持链式调用

- `add_system_message(content)`: 添加系统消息
  - `content`: 系统消息内容
  - 返回值: 自身，支持链式调用

- `add_user_message(content)`: 添加用户消息
  - `content`: 用户消息内容，可以是字符串或包含图片和文本的列表
  - 返回值: 自身，支持链式调用

- `add_assistant_message(content)`: 添加助手消息
  - `content`: 助手消息内容
  - 返回值: 自身，支持链式调用

- `add_image_message(image_url, text)`: 添加包含图片和文本的用户消息
  - `image_url`: 图片 URL
  - `text`: 文本内容
  - 返回值: 自身，支持链式调用

- `build()`: 构建消息列表
  - 返回值: 消息列表，格式为 `[{"role": "...", "content": [...]}]`

## 项目结构

```
phad-llm-sdk/
├── src/
│   └── phad_llm_sdk/
│       ├── client/
│       │   ├── LLMClient.py      # 主要客户端实现
│       │   ├── VLLMClient.py     # VLLM 客户端实现
│       │   └── __init__.py
│       ├── dto/
│       │   ├── req/              # 请求数据模型
│       │   │   ├── __init__.py
│       │   │   └── llm_send.py
│       │   ├── resp/             # 响应数据模型
│       │   │   ├── __init__.py
│       │   │   └── llm_resp.py
│       │   └── __init__.py
│       ├── utils/
│       │   ├── HttpUtils.py      # HTTP 工具类
│       │   └── __init__.py
│       └── __init__.py           # 包导出文件
├── pyproject.toml                 # 项目配置文件
├── setup.py                       # 安装脚本
├── setup.cfg                      # 安装配置文件
├── requirements.txt               # 依赖文件
├── README.md                      # 项目说明文件
└── LICENSE                        # 许可证文件
```

## 配置示例

### .env 文件示例

```
# LLMClient 配置
VLLM_LLM_URL=http://localhost:8000
LLM_QWEN_PATH=v1/chat/completions

# VLLMClient 配置
VLLM_VLLM_URL=http://localhost:8000
VLLM_QWEN_PATH=v1/chat/completions
```

## 故障排除

### 常见问题

1. **连接失败**：请检查 `VLLM_LLM_URL`（LLMClient）或 `VLLM_VLLM_URL`（VLLMClient）环境变量是否正确配置，确保大模型服务正在运行。

2. **API 路径问题**：如果需要自定义 API 路径，请检查 `LLM_QWEN_PATH`（LLMClient）或 `VLLM_QWEN_PATH`（VLLMClient）环境变量是否正确配置。

3. **导入错误**：请确保已正确安装 SDK，并且 Python 版本 >= 3.7。

4. **响应异常**：请检查请求参数是否正确，特别是消息格式是否符合要求。

### 日志调试

如果遇到问题，可以开启详细日志来排查：

```python
import logging
logging.basicConfig(level=logging.DEBUG)

from phad_llm_sdk import llm_client
# 后续代码...
```

## 版本历史

- **v1.2.3**：修复导入问题，优化包结构
- **v1.2.1**：更新依赖版本，支持最新 Python 版本
- **v0.1.0**：初始版本，支持基本的大模型调用和流式响应

## 测试图片链接

以下是一些可以用于测试 VLLM SDK 多模态功能的图片链接：

### 风景图片
- `https://picsum.photos/id/10/800/600` - 森林风景
- `https://picsum.photos/id/15/800/600` - 山脉风景
- `https://picsum.photos/id/18/800/600` - 海滩风景

### 人物图片
- `https://picsum.photos/id/64/800/600` - 人物肖像
- `https://picsum.photos/id/65/800/600` - 儿童图片

### 动物图片
- `https://picsum.photos/id/237/800/600` - 狗
- `https://picsum.photos/id/433/800/600` - 狮子

### 城市建筑
- `https://picsum.photos/id/1002/800/600` - 城市夜景
- `https://picsum.photos/id/1006/800/600` - 建筑外观

### 食物图片
- `https://picsum.photos/id/292/800/600` - 披萨
- `https://picsum.photos/id/488/800/600` - 水果

这些链接来自 picsum.photos，是一个免费的测试图片服务。

## 常见问题

### 1. 如何选择使用 LLMClient 还是 VLLMClient？

- **LLMClient**：适用于纯文本对话场景，支持返回思考过程
- **VLLMClient**：适用于需要处理图片的多模态场景，支持图片分析和描述

### 2. 如何处理流式响应？

流式响应会逐块返回数据，需要解析 SSE（Server-Sent Events）格式的数据。SDK 提供了示例代码，可以参考快速开始部分。

### 3. 支持哪些图片格式？

目前支持通过 URL 提供的图片，常见的图片格式（JPG、PNG、GIF 等）都可以正常工作。

### 4. 如何自定义模型路径？

可以通过环境变量 `VLLM_QWEN_PATH` 或 `LLM_QWEN_PATH` 来自定义 API 路径，也可以在代码中直接修改客户端的 `url` 属性。

## 许可证

本项目采用 MIT 许可证，详见 [LICENSE](LICENSE) 文件。

## 贡献

欢迎提交 Issue 和 Pull Request 来改进这个 SDK。

## 联系方式

- 项目地址：[https://github.com/yourusername/phad-llm-sdk-python](https://github.com/yourusername/phad-llm-sdk-python)
- 邮箱：1714873054@qq.com
- 作者：令狐荣豪
