GLM 5.2 智能体工作流:函数调用、工具使用与多步骤任务
Jul 23, 2026

GLM 5.2 智能体工作流:函数调用、工具使用与多步骤任务

用 GLM 5.2 构建生产级 AI 智能体——函数调用、并行工具执行与多步骤推理,全程附可直接运行的 Python 示例。

构建可靠的 AI 智能体,模型需要具备三样东西:准确的函数调用、在众多步骤间不丢上下文的推理能力,以及不会让项目中途破产的经济性。GLM 5.2(API 模型名 glm-4-plus)三项全中。它支持 OpenAI 兼容的工具调用,能在单次响应里并行执行多个函数调用,上下文最高容纳 1,048,576 token,输入价格为每百万 token 1.40 美元。本教程带你走完搭建生产级智能体的全部环节——从单次工具调用到完整的多步骤 ReAct 循环——每一步都附带可运行的 Python 代码。

为什么智能体场景会把多数模型逼到极限

每个智能体开发者都会撞上的痛点不是第一次工具调用——而是当智能体需要协调二十轮对话中的十个工具、同时把一份 50 页的知识库装进上下文时。那一刻,GPT-4o 的上下文上限成了路障,每 token 成本开始以让多步骤循环在经济上难以为继的方式复利增长。

GLM 5.2 的 1M-token 上下文窗口不是营销数字——它直接改变了架构上可能的事。你可以把整个代码库、一整套文档语料、或几十个先前的工具结果装进同一个上下文,无需切块或检索技巧。以每百万输入 token 1.40 美元的价格,即使一次 200K-token 的智能体循环,每轮成本也不到 0.30 美元。对文档密集型任务——法律审查、财务分析、代码审计——这个组合是真正解锁,是更贵的模型在规模上也难以匹敌的。

为什么 GLM 5.2 是智能体的正确地基

在进入代码之前,先说说为什么 glm-4-plus 特别适合智能体工作:

  • OpenAI 兼容的工具规范——tools 参数格式与 OpenAI API 完全一致,任何现有智能体代码(LangChain、LlamaIndex、AutoGen、CrewAI)只需改两行即可工作:base_urlmodel
  • 并行函数调用——模型可以在单次响应中返回多个 tool_calls,让你同时从多个数据源取数,而不是串行等待。
  • 可靠的指令跟随——GPQA Diamond 89%、SWE-bench Pro 62.1% 的成绩,反映了模型仔细推理、跟随复杂多步骤指令的能力。
  • JSON 模式——设置 response_format={"type": "json_object"},模型保证输出可解析的 JSON,这对结构化智能体状态管理至关重要。
  • MIT 许可的开放权重——模型权重以 MIT 许可证发布在 HuggingFace 上,因此延迟敏感或数据私密的工作负载可以选择自托管部署。

完整的 API 配置细节见 GLM 5.2 API 指南,其中覆盖认证、端点和流式配置。

准备工作:客户端与环境

安装 openai 包——不需要单独的 GLM SDK:

pip install openai

配置客户端指向 Zhipu 的 API:

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ZHIPU_API_KEY"],
    base_url="https://open.bigmodel.cn/api/paas/v4/",
)
MODEL = "glm-4-plus"

在环境中设置 ZHIPU_API_KEY。本教程其余部分都使用这个 client 对象。


如果你想在写任何代码之前先体验 GLM 5.2,glm5.app 可以让你跑提示词、交互式测试工具调用、看到实时响应——在把工具 schema 固化进生产代码之前,先做原型很有用。


第 1 步:单次函数调用

任何智能体的积木都是单次工具调用。定义一个工具 schema,通过 tools 参数传入,让模型决定是否调用它。

import json

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_stock_price",
            "description": "Returns the latest closing price for a given stock ticker symbol.",
            "parameters": {
                "type": "object",
                "properties": {
                    "ticker": {
                        "type": "string",
                        "description": "The stock ticker, e.g. AAPL or TSLA",
                    }
                },
                "required": ["ticker"],
            },
        },
    }
]

messages = [
    {"role": "system", "content": "You are a financial research assistant."},
    {"role": "user", "content": "What is the current price of AAPL?"},
]

response = client.chat.completions.create(
    model=MODEL,
    messages=messages,
    tools=tools,
    tool_choice="auto",
)

message = response.choices[0].message

if message.tool_calls:
    call = message.tool_calls[0]
    print(f"Tool called: {call.function.name}")
    print(f"Arguments: {call.function.arguments}")
else:
    print(message.content)

当模型判定某个工具合适时,它会返回一个 tool_calls 列表而不是文字答案。你的应用随后执行真正的函数(一次真实的 API 调用、数据库查询或计算),并把结果喂回去。

第 2 步:闭环——返回工具结果

智能体循环就是一个 while 循环:调用模型、检查它是否想要工具、执行工具、把结果追加进消息、再次调用模型。下面是一个完整的单工具循环:

def run_agent(user_message: str, tools: list, tool_map: dict) -> str:
    """
    Simple agent loop. tool_map maps function names to Python callables.
    Returns the model's final text response.
    """
    messages = [
        {"role": "system", "content": "You are a helpful research assistant."},
        {"role": "user", "content": user_message},
    ]

    while True:
        response = client.chat.completions.create(
            model=MODEL,
            messages=messages,
            tools=tools,
            tool_choice="auto",
        )
        message = response.choices[0].message

        # No tool calls — model is done reasoning, return final answer
        if not message.tool_calls:
            return message.content

        # Append the assistant's tool-call message to history
        messages.append(message)

        # Execute each tool call and append results
        for call in message.tool_calls:
            fn = tool_map.get(call.function.name)
            if fn is None:
                result = f"Error: unknown function {call.function.name}"
            else:
                args = json.loads(call.function.arguments)
                result = fn(**args)

            messages.append(
                {
                    "role": "tool",
                    "tool_call_id": call.id,
                    "content": str(result),
                }
            )
        # Loop back — model will reason over the tool results

关键细节是 role: "tool" 消息。每个工具结果必须携带匹配的 tool_call_id,这样当多个工具同时被调用时,模型才能把结果与调用对应起来。

第 3 步:并行工具调用

GLM 5.2 可以在单次响应中返回多个工具调用。这让你能同时获取相互独立的数据源,而不是等每个完成再要下一个。代码改动很小——你已经是在处理 tool_calls 列表了——但当工具涉及 I/O 时,生产环境下的性能差异非常显著。

import concurrent.futures

def run_agent_parallel(user_message: str, tools: list, tool_map: dict) -> str:
    messages = [
        {"role": "system", "content": "You are a market analysis assistant. "
         "When you need multiple data points, fetch them in parallel."},
        {"role": "user", "content": user_message},
    ]

    while True:
        response = client.chat.completions.create(
            model=MODEL,
            messages=messages,
            tools=tools,
            tool_choice="auto",
        )
        message = response.choices[0].message

        if not message.tool_calls:
            return message.content

        messages.append(message)

        # Execute all tool calls in parallel
        def execute_call(call):
            fn = tool_map.get(call.function.name)
            if fn is None:
                return call.id, f"Error: unknown function {call.function.name}"
            args = json.loads(call.function.arguments)
            return call.id, fn(**args)

        with concurrent.futures.ThreadPoolExecutor() as executor:
            results = list(executor.map(execute_call, message.tool_calls))

        for call_id, result in results:
            messages.append(
                {
                    "role": "tool",
                    "tool_call_id": call_id,
                    "content": str(result),
                }
            )

当被问到「对比 AAPL、MSFT 和 GOOGL 的营收」时,模型可以同时发出三个 get_revenue 调用。你的线程池并行执行它们,一次性把三个结果全部返回。墙钟时间是最慢的那一次调用,而不是三者之和。

第 4 步:带 JSON 状态的多步骤 ReAct 智能体

对于需要规划的任务——「调研这个主题,写一份结构化报告,再按这些约束检查一遍」——ReAct(Reason + Act)模式给模型在每个动作之前留出思考空间。再结合 response_format={"type": "json_object"},就能得到可记录、可检查、可恢复的结构化中间状态。

REACT_SYSTEM = """You are a research agent using the ReAct pattern.
At each step, respond with a JSON object:
{
  "thought": "your reasoning about what to do next",
  "action": "tool_name or 'finish'",
  "action_input": { ...tool arguments... },
  "final_answer": "only present when action is 'finish'"
}
Never skip the thought field. Be explicit about why you chose each action."""

def react_agent(task: str, tools: list, tool_map: dict, max_steps: int = 10) -> str:
    messages = [
        {"role": "system", "content": REACT_SYSTEM},
        {"role": "user", "content": task},
    ]

    for step in range(max_steps):
        response = client.chat.completions.create(
            model=MODEL,
            messages=messages,
            response_format={"type": "json_object"},
            # Pass tools as context but let the model decide via JSON
        )
        raw = response.choices[0].message.content
        state = json.loads(raw)

        print(f"\nStep {step + 1} thought: {state.get('thought', '')}")

        action = state.get("action")
        if action == "finish":
            return state.get("final_answer", "")

        fn = tool_map.get(action)
        if fn is None:
            tool_result = f"Error: unknown action '{action}'"
        else:
            tool_result = fn(**state.get("action_input", {}))

        messages.append({"role": "assistant", "content": raw})
        messages.append(
            {"role": "user", "content": f"Observation: {tool_result}\nContinue."}
        )

    return "Max steps reached without finishing."

JSON 模式的保证意味着 json.loads(raw) 不会在循环中途抛出解析错误。有了 1M-token 上下文,完整的推理轨迹——每一步的 thought、action 和 observation——在全部十步里都留在上下文中,不会被截断。

第 5 步:框架集成

如果你已经在用某个框架,集成只需两行:

LangChain

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="glm-4-plus",
    openai_api_key=os.environ["ZHIPU_API_KEY"],
    openai_api_base="https://open.bigmodel.cn/api/paas/v4/",
)
# Use llm in any LangChain agent, chain, or tool-calling wrapper

AutoGen

config_list = [
    {
        "model": "glm-4-plus",
        "api_key": os.environ["ZHIPU_API_KEY"],
        "base_url": "https://open.bigmodel.cn/api/paas/v4/",
    }
]
# Pass config_list to AssistantAgent or UserProxyAgent as llm_config

LlamaIndex

from llama_index.llms.openai import OpenAI as LlamaOpenAI

llm = LlamaOpenAI(
    model="glm-4-plus",
    api_key=os.environ["ZHIPU_API_KEY"],
    api_base="https://open.bigmodel.cn/api/paas/v4/",
)

三个框架在底层发送的都是标准 OpenAI 格式的工具 schema,GLM 5.2 无需任何修改即可处理。

为你的智能体选对 GLM 模型

除了 glm-4-plus,Zhipu 还提供多个模型。对智能体工作流来说,权衡如下:

模型最适合输入价格
glm-4-plus(GLM 5.2)复杂推理、长上下文、多步骤智能体$1.40 / 1M token
glm-4-air轻量路由、廉价子智能体$0.10 / 1M token(约)
glm-4-long长文档摄取预处理$1.00 / 1M token(约)
embedding-3语义搜索、RAG 检索按 Embedding 计价

一种常见的生产架构是分层设计:用 glm-4-air 做快速路由,识别意图,只在需要深度推理的任务上分发给 glm-4-plus。这样平均成本保持低位,同时关键处质量不丢。

生产注意事项

错误处理与重试。 工具结果可能是畸形或空的。用 try/except 包住工具执行并返回结构化的错误字符串——模型能优雅地处理 "Error: API timeout",自行决定重试或走替代路径。

上下文管理。 在 1M token 下,GLM 5.2 很少需要激进裁剪。不过对极长运行的智能体,考虑在上下文填满前用廉价模型总结旧观察。保留最近 N 条完整工具结果,加一份更早内容的摘要。

流式工具调用。stream=True 即可在工具调用 delta 到达时实时获取。这在工具结果返回前向用户展示「正在处理」很有用。工具调用的流式格式与 OpenAI 流式规范完全一致。

速率限制与成本监控。 每秒 158 token(Artificial Analysis 基准)的吞吐量对单用户智能体来说很扎实。对批量智能体工作负载,用 Zhipu 的批量 API 在夜间以更低成本处理大量任务。

下一步

本教程的模式——单次工具调用、并行执行、ReAct JSON 循环、框架集成——覆盖了多数生产智能体架构。变化的是你带来的工具集:网络搜索、数据库查询、代码执行、文件 I/O、外部 API。

GLM 5.2 的 1M-token 上下文和 OpenAI 兼容接口意味着你可以快速迭代,把完整对话历史与全部工具结果留在上下文中,不必跟检索或切块较劲。价格让多步骤循环在生产规模下经济上完全可行。

glm5.app 开始构建和测试你的智能体工具——playground 可以让你在接入后端之前先原型化工具 schema、观察模型行为。

Sources

Start Using GLM 5 Today

Try GLM 5 free — reasoning, coding, agents, and image generation in one platform.