Skip to content

智谱AI GLM API完全指南

智谱AI是国内领先的AI公司,其GLM系列模型在中文理解和生成方面表现出色

概述

智谱AI是清华大学技术团队创立的AI公司,其GLM(General Language Model)系列模型在中文理解、代码生成和长文本处理方面表现出色。本教程将带你全面掌握智谱AI API的使用方法。

为什么选择智谱AI?

优势说明
中文能力强专为中文优化,理解准确
清华技术清华大学技术团队支持
长文本处理支持超长上下文
多模态支持支持文本、图像理解

GLM模型概览

GLM模型家族:

GLM-4系列(最新)
├── glm-4-plus          # 最强能力
├── glm-4-0520          # 高性能版本
├── glm-4-air           # 快速版本
├── glm-4-airx          # 极速版本
├── glm-4-long          # 长上下文版本
└── glm-4v              # 多模态版本

GLM-3系列(经典)
└── glm-3-turbo         # 经典版本

专业模型
├── codegeex-4          # 代码专用
└── embedding-3         # 嵌入模型

基本概念

API Key

php
<?php
// 在智谱AI开放平台获取API Key
// https://open.bigmodel.cn/

// API Key格式
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

$apiKey = getenv('ZHIPU_API_KEY');

JWT认证

智谱AI使用JWT认证方式:

php
<?php
// API Key格式:id.secret
// 需要生成JWT Token进行认证

function generateToken(string $apiKey): string
{
    list($id, $secret) = explode('.', $apiKey);
    
    $header = base64_encode(json_encode(['alg' => 'HS256', 'sign_type' => 'SIGN']));
    $payload = base64_encode(json_encode([
        'api_key' => $id,
        'exp' => time() + 3600,
        'timestamp' => time() * 1000,
    ]));
    
    $signature = hash_hmac('sha256', $header . '.' . $payload, $secret, true);
    $signature = base64_encode($signature);
    
    return $header . '.' . $payload . '.' . $signature;
}

环境准备

创建智谱AI客户端

php
<?php
require 'vendor/autoload.php';

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

class ZhipuClient
{
    private $client;
    private $apiKey;
    private $baseUrl = 'https://open.bigmodel.cn/api/paas/v4';

    public function __construct(string $apiKey)
    {
        $this->apiKey = $apiKey;
        $this->client = new Client([
            'base_uri' => $this->baseUrl,
            'timeout' => 120,
            'headers' => [
                'Authorization' => 'Bearer ' . $this->generateToken(),
                'Content-Type' => 'application/json',
            ],
        ]);
    }

    private function generateToken(): string
    {
        list($id, $secret) = explode('.', $this->apiKey);
        
        $header = $this->base64UrlEncode(json_encode(['alg' => 'HS256', 'sign_type' => 'SIGN']));
        $payload = $this->base64UrlEncode(json_encode([
            'api_key' => $id,
            'exp' => time() + 3600,
            'timestamp' => time() * 1000,
        ]));
        
        $signature = hash_hmac('sha256', $header . '.' . $payload, $secret, true);
        $signature = $this->base64UrlEncode($signature);
        
        return $header . '.' . $payload . '.' . $signature;
    }

    private function base64UrlEncode(string $data): string
    {
        return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
    }

    public function chat(
        array $messages,
        string $model = 'glm-4-air',
        array $options = []
    ): array {
        $params = [
            'model' => $model,
            'messages' => $messages,
        ];

        if (isset($options['temperature'])) {
            $params['temperature'] = $options['temperature'];
        }

        if (isset($options['max_tokens'])) {
            $params['max_tokens'] = $options['max_tokens'];
        }

        if (isset($options['top_p'])) {
            $params['top_p'] = $options['top_p'];
        }

        try {
            $response = $this->client->post('/chat/completions', [
                'json' => $params,
            ]);

            return json_decode($response->getBody(), true);
        } catch (RequestException $e) {
            $errorBody = $e->getResponse() ? $e->getResponse()->getBody()->getContents() : 'Unknown error';
            throw new Exception('智谱AI API Error: ' . $errorBody);
        }
    }
}

// 使用示例
$apiKey = getenv('ZHIPU_API_KEY');
$client = new ZhipuClient($apiKey);

$result = $client->chat([
    ['role' => 'user', 'content' => '请用一句话介绍PHP语言']
]);

echo $result['choices'][0]['message']['content'];

运行结果:

PHP是一种开源的服务器端脚本语言,特别适合Web开发,可以嵌入HTML中执行。

高级参数配置

完整参数示例

php
<?php
class ZhipuClient
{
    // ... 前面的代码 ...

    public function chatAdvanced(
        array $messages,
        string $model = 'glm-4-air',
        array $options = []
    ): array {
        $params = [
            'model' => $model,
            'messages' => $messages,
        ];

        $optionalParams = [
            'temperature',
            'max_tokens',
            'top_p',
            'stop',
            'tools',
            'tool_choice',
        ];

        foreach ($optionalParams as $param) {
            if (isset($options[$param])) {
                $params[$param] = $options[$param];
            }
        }

        try {
            $response = $this->client->post('/chat/completions', [
                'json' => $params,
            ]);

            return json_decode($response->getBody(), true);
        } catch (RequestException $e) {
            $errorBody = $e->getResponse() ? $e->getResponse()->getBody()->getContents() : 'Unknown error';
            throw new Exception('智谱AI API Error: ' . $errorBody);
        }
    }
}

// 使用示例
$result = $client->chatAdvanced(
    [['role' => 'user', 'content' => '写一首关于程序员的诗']],
    'glm-4-air',
    [
        'temperature' => 0.8,
        'max_tokens' => 500,
    ]
);

参数详解

参数范围默认值说明
temperature0-10.95控制随机性
max_tokens1-模型上限无限制最大输出Token
top_p0-10.7核采样参数
stop字符串或数组-停止序列
tools数组-工具定义
tool_choice字符串-工具选择策略

流式响应处理

php
<?php
class ZhipuClient
{
    // ... 前面的代码 ...

    public function chatStream(
        array $messages,
        string $model = 'glm-4-air'
    ): Generator {
        $response = $this->client->post('/chat/completions', [
            'json' => [
                'model' => $model,
                'messages' => $messages,
                'stream' => true,
            ],
            'stream' => true,
        ]);

        $body = $response->getBody();
        $buffer = '';

        while (!$body->eof()) {
            $chunk = $body->read(1024);
            $buffer .= $chunk;

            while (($pos = strpos($buffer, "\n")) !== false) {
                $line = substr($buffer, 0, $pos);
                $buffer = substr($buffer, $pos + 1);

                $line = trim($line);
                if (empty($line) || $line === 'data: [DONE]') {
                    continue;
                }

                if (strpos($line, 'data: ') === 0) {
                    $json = substr($line, 6);
                    $data = json_decode($json, true);

                    if (isset($data['choices'][0]['delta']['content'])) {
                        yield $data['choices'][0]['delta']['content'];
                    }
                }
            }
        }
    }
}

// 使用示例
echo "GLM回复:";
foreach ($client->chatStream([['role' => 'user', 'content' => '讲一个程序员笑话']]) as $chunk) {
    echo $chunk;
    flush();
}

长文本处理

使用glm-4-long处理长文档

php
<?php
class LongDocumentProcessor
{
    private ZhipuClient $client;

    public function __construct(ZhipuClient $client)
    {
        $this->client = $client;
    }

    public function analyzeDocument(string $document, string $question): string
    {
        $result = $this->client->chat(
            [
                [
                    'role' => 'user',
                    'content' => "文档内容:\n{$document}\n\n问题:{$question}"
                ]
            ],
            'glm-4-long',
            ['max_tokens' => 4096]
        );

        return $result['choices'][0]['message']['content'];
    }

    public function summarizeDocument(string $document, int $maxLength = 500): string
    {
        $result = $this->client->chat(
            [
                [
                    'role' => 'user',
                    'content' => "请将以下文档总结为不超过{$maxLength}字:\n\n{$document}"
                ]
            ],
            'glm-4-long'
        );

        return $result['choices'][0]['message']['content'];
    }
}

多模态处理

使用GLM-4V进行图像理解

php
<?php
class GLMVClient
{
    private $client;
    private $apiKey;
    private $baseUrl = 'https://open.bigmodel.cn/api/paas/v4';

    public function __construct(string $apiKey)
    {
        $this->apiKey = $apiKey;
        $this->client = new Client([
            'base_uri' => $this->baseUrl,
            'timeout' => 120,
            'headers' => [
                'Authorization' => 'Bearer ' . $this->generateToken(),
                'Content-Type' => 'application/json',
            ],
        ]);
    }

    private function generateToken(): string
    {
        list($id, $secret) = explode('.', $this->apiKey);
        $header = rtrim(strtr(base64_encode(json_encode(['alg' => 'HS256', 'sign_type' => 'SIGN'])), '+/', '-_'), '=');
        $payload = rtrim(strtr(base64_encode(json_encode([
            'api_key' => $id,
            'exp' => time() + 3600,
            'timestamp' => time() * 1000,
        ])), '+/', '-_'), '=');
        $signature = rtrim(strtr(base64_encode(hash_hmac('sha256', $header . '.' . $payload, $secret, true)), '+/', '-_'), '=');
        return $header . '.' . $payload . '.' . $signature;
    }

    public function analyzeImage(string $imageUrl, string $question): string
    {
        $response = $this->client->post('/chat/completions', [
            'json' => [
                'model' => 'glm-4v',
                'messages' => [
                    [
                        'role' => 'user',
                        'content' => [
                            ['type' => 'image_url', 'image_url' => ['url' => $imageUrl]],
                            ['type' => 'text', 'text' => $question],
                        ],
                    ],
                ],
            ],
        ]);

        $result = json_decode($response->getBody(), true);
        return $result['choices'][0]['message']['content'];
    }

    public function describeImage(string $imageUrl): string
    {
        return $this->analyzeImage($imageUrl, '请详细描述这张图片的内容');
    }

    public function ocr(string $imageUrl): string
    {
        return $this->analyzeImage($imageUrl, '请识别图片中的所有文字');
    }
}

常见错误与踩坑点

错误1:JWT Token过期

php
<?php
// ❌ 错误做法:长时间使用同一个Token
$client = new ZhipuClient($apiKey);
// 几小时后Token过期

// ✅ 正确做法:每次请求生成新Token
class ZhipuClient
{
    private function refreshToken(): void
    {
        $this->token = $this->generateToken();
        $this->tokenExpireTime = time() + 3500; // 提前100秒刷新
    }

    public function chat(array $messages, string $model = 'glm-4-air'): array
    {
        if (time() >= $this->tokenExpireTime) {
            $this->refreshToken();
        }
        // ...
    }
}

错误2:模型名称错误

php
<?php
// ❌ 错误做法:使用不存在的模型
$result = $client->chat($messages, 'glm-4');

// ✅ 正确做法:使用正确的模型名称
$result = $client->chat($messages, 'glm-4-air');
$result = $client->chat($messages, 'glm-4-plus');
$result = $client->chat($messages, 'glm-4-long');

错误3:忽略速率限制

php
<?php
// ❌ 错误做法:快速连续请求
foreach ($prompts as $prompt) {
    $result = $client->chat([['role' => 'user', 'content' => $prompt]]);
}

// ✅ 正确做法:添加请求间隔
foreach ($prompts as $prompt) {
    $result = $client->chat([['role' => 'user', 'content' => $prompt]]);
    usleep(500000); // 500ms间隔
}

常见应用场景

场景1:智能客服

php
<?php
class ZhipuCustomerService
{
    private ZhipuClient $client;
    private array $knowledgeBase = [];

    public function addKnowledge(string $category, string $content): void
    {
        $this->knowledgeBase[$category] = $content;
    }

    public function handleQuery(string $query): string
    {
        $context = '';
        foreach ($this->knowledgeBase as $category => $content) {
            $context .= "【{$category}】\n{$content}\n\n";
        }

        $result = $this->client->chat([
            [
                'role' => 'system',
                'content' => '你是一个友好的客服助手。请根据知识库回答问题。'
            ],
            [
                'role' => 'user',
                'content' => "知识库:\n{$context}\n\n客户问题:{$query}"
            ]
        ]);

        return $result['choices'][0]['message']['content'];
    }
}

场景2:代码助手

php
<?php
class CodeGeeXAssistant
{
    private ZhipuClient $client;

    public function generateCode(string $description, string $language = 'PHP'): string
    {
        $result = $this->client->chat(
            [
                [
                    'role' => 'user',
                    'content' => "请生成{$language}代码:{$description}"
                ]
            ],
            'glm-4-air'
        );

        return $result['choices'][0]['message']['content'];
    }

    public function explainCode(string $code): string
    {
        $result = $this->client->chat([
            ['role' => 'user', 'content' => "请解释以下代码:\n```\n{$code}\n```"]
        ]);

        return $result['choices'][0]['message']['content'];
    }
}

场景3:文档问答

php
<?php
class ZhipuDocumentQA
{
    private ZhipuClient $client;
    private string $document;

    public function loadDocument(string $filePath): void
    {
        $this->document = file_get_contents($filePath);
    }

    public function ask(string $question): string
    {
        $result = $this->client->chat(
            [
                [
                    'role' => 'user',
                    'content' => "文档内容:\n{$this->document}\n\n问题:{$question}"
                ]
            ],
            'glm-4-long'
        );

        return $result['choices'][0]['message']['content'];
    }
}

场景4:内容创作

php
<?php
class ZhipuContentCreator
{
    private ZhipuClient $client;

    public function generateArticle(string $topic, int $wordCount = 800): string
    {
        $result = $this->client->chat([
            [
                'role' => 'user',
                'content' => "请写一篇关于{$topic}的文章,字数约{$wordCount}字。"
            ]
        ]);

        return $result['choices'][0]['message']['content'];
    }
}

场景5:图像分析

php
<?php
class ZhipuImageAnalyzer
{
    private GLMVClient $client;

    public function describeImage(string $imageUrl): string
    {
        return $this->client->describeImage($imageUrl);
    }

    public function extractText(string $imageUrl): string
    {
        return $this->client->ocr($imageUrl);
    }
}

常见问题答疑(FAQ)

Q1:智谱AI的定价如何?

回答

模型输入价格输出价格
glm-4-air¥0.1/千Token¥0.1/千Token
glm-4-airx¥0.1/千Token¥0.1/千Token
glm-4-plus¥0.05/千Token¥0.05/千Token
glm-4-long¥0.001/千Token¥0.001/千Token

Q2:如何选择合适的模型?

回答

场景推荐模型原因
快速响应glm-4-airx速度最快
复杂任务glm-4-plus能力最强
长文档glm-4-long支持长上下文
图像理解glm-4v多模态支持

Q3:如何处理JWT Token过期?

回答

php
<?php
// Token有效期1小时,建议每次请求前检查并刷新
class ZhipuClient
{
    private int $tokenExpireTime = 0;

    private function ensureValidToken(): void
    {
        if (time() >= $this->tokenExpireTime) {
            $this->token = $this->generateToken();
            $this->tokenExpireTime = time() + 3500;
        }
    }
}

Q4:如何处理API错误?

回答

php
<?php
function handleZhipuError(Exception $e): string
{
    $message = $e->getMessage();

    if (strpos($message, 'invalid_api_key') !== false) {
        return 'API Key无效';
    }
    if (strpos($message, 'rate_limit') !== false) {
        return '请求过于频繁';
    }
    if (strpos($message, 'insufficient_quota') !== false) {
        return '账户余额不足';
    }

    return '服务暂时不可用';
}

Q5:如何使用函数调用?

回答

php
<?php
$tools = [
    [
        'type' => 'function',
        'function' => [
            'name' => 'get_weather',
            'description' => '获取指定城市的天气',
            'parameters' => [
                'type' => 'object',
                'properties' => [
                    'city' => ['type' => 'string', 'description' => '城市名称'],
                ],
                'required' => ['city'],
            ],
        ],
    ],
];

$result = $client->chatAdvanced(
    [['role' => 'user', 'content' => '北京今天天气怎么样?']],
    'glm-4-air',
    ['tools' => $tools]
);

Q6:如何获取文本嵌入?

回答

php
<?php
class ZhipuEmbedding
{
    private $client;
    private $apiKey;

    public function embed(string $text): array
    {
        $response = $this->client->post('/embeddings', [
            'json' => [
                'model' => 'embedding-3',
                'input' => $text,
            ],
        ]);

        $result = json_decode($response->getBody(), true);
        return $result['data'][0]['embedding'];
    }
}

实战练习

基础练习

练习1:编写一个简单的GLM聊天程序。

参考代码

php
<?php
$apiKey = getenv('ZHIPU_API_KEY');
$client = new ZhipuClient($apiKey);

echo "GLM聊天助手 (输入 'quit' 退出)\n";

while (true) {
    echo "\n你: ";
    $input = trim(fgets(STDIN));

    if ($input === 'quit') {
        break;
    }

    $result = $client->chat([['role' => 'user', 'content' => $input]]);
    echo "GLM: " . $result['choices'][0]['message']['content'] . "\n";
}

进阶练习

练习2:实现一个长文档摘要工具。

参考代码

php
<?php
class DocumentSummarizer
{
    private ZhipuClient $client;

    public function summarize(string $document, int $maxLength = 500): string
    {
        $result = $this->client->chat(
            [
                ['role' => 'user', 'content' => "请总结以下文档,不超过{$maxLength}字:\n\n{$document}"]
            ],
            'glm-4-long'
        );

        return $result['choices'][0]['message']['content'];
    }
}

挑战练习

练习3:构建一个多模态内容分析系统。

参考代码

php
<?php
class MultimodalAnalyzer
{
    private ZhipuClient $textClient;
    private GLMVClient $imageClient;

    public function analyze(array $content): array
    {
        $results = [];

        foreach ($content as $item) {
            if ($item['type'] === 'text') {
                $result = $this->textClient->chat([
                    ['role' => 'user', 'content' => "分析以下文本:\n{$item['data']}"]
                ]);
                $results[] = ['type' => 'text', 'analysis' => $result['choices'][0]['message']['content']];
            } elseif ($item['type'] === 'image') {
                $results[] = ['type' => 'image', 'analysis' => $this->imageClient->describeImage($item['data'])];
            }
        }

        return $results;
    }
}

知识点总结

核心要点

  1. JWT认证:使用JWT Token进行认证
  2. 中文能力强:专为中文优化
  3. 长文本处理:glm-4-long支持长上下文
  4. 多模态支持:glm-4v支持图像理解
  5. 清华技术:清华大学技术团队支持

易错点回顾

易错点正确做法
JWT Token过期定期刷新Token
模型名称错误使用正确的模型名称
忽略速率限制添加请求间隔
不使用专用模型长文档使用glm-4-long

拓展参考资料

官方文档

进阶学习路径

  1. 本知识点 → 智谱AI API基础使用
  2. 下一步月之暗面Kimi
  3. 进阶错误处理与重试
  4. 高级安全与鉴权

💡 记住:智谱AI的JWT认证方式需要特别注意Token过期问题,善用glm-4-long可以处理超长文档。