news 2026/10/4 7:18:17

ChatGLM3 Composite Web Demo 实战指南:三种交互模式、工具注册与代码解释器的完整解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ChatGLM3 Composite Web Demo 实战指南:三种交互模式、工具注册与代码解释器的完整解析
  • 大模型
  • 人工智能
  • 微调
  • 本地部署
  • AI Agent
  • RAG

【免费下载链接】ChatGLM3

ChatGLM3 series: Open Bilingual Chat LLMs | 开源双语对话语言模型

项目地址:https://gitcode.com/gh_mirrors/ch/ChatGLM3
点击查看免费下载

本文以仓库composite_demo目录下的 README_en.md 为骨架,系统讲解 ChatGLM3 官方复合 Web Demo 的安装、启动与三种核心交互模式(对话 Chat、工具 Tool、代码解释器 Code Interpreter),并结合该目录下的main.py、tool_registry.py、client.py、demo_ci.py等源码逐一验证实现细节。读完本文,你将掌握如何一键在本地启动该 Demo、如何用@register_tool扩展模型工具能力、如何在 Jupyter 内核中让模型自动编写并执行代码,以及如何通过环境变量与侧边栏参数精确控制模型的推理行为。

一、Demo 概览:一个页面承载三种能力

ChatGLM3 Composite Web Demo 是一个基于Streamlit构建的单页应用,它把 ChatGLM3 最常用的三种交互形态整合到同一界面中,通过顶部的单选按钮(💬 Chat、🛠️ Tool、🧑💻 Code Interpreter)随时切换:

  • Chat(对话模式):与模型进行纯文本多轮对话;
  • Tool(工具模式):模型在对话之外,可以调用注册好的外部工具完成操作;
  • Code Interpreter(代码解释器模式):模型在一个 Jupyter 内核环境中执行代码、读取执行结果,从而完成绘图、符号运算等复杂任务。

Demo 的主页面外观如下:

整个 Demo 的代码组织非常清晰(详见 composite_demo 目录):

文件职责
main.pyStreamlit 入口,负责侧边栏参数、模式切换与三个子模块的调度
demo_chat.py对话模式的核心逻辑
demo_tool.py工具模式的界面与工具调用循环
demo_ci.py代码解释器模式,封装 Jupyter 内核的启动与代码执行
client.py模型加载与流式生成客户端(HFClient)
conversation.py对话轮次Conversation数据结构与 ChatGLM3 特殊 token(<|system|>、<|user|>、<|assistant|>、<|observation|>)的封装
tool_registry.py工具的注册、描述生成与分发执行

main.py的核心调度逻辑如下(对应 main.py):根据当前选中的模式,把侧边栏的生成参数分别传给demo_chat.main、demo_tool.main或demo_ci.main,其中 Tool 与 Code Interpreter 模式额外传入truncate_length=1024用于截断过长的工具返回结果。

二、环境安装与依赖

官方文档建议通过Conda管理环境。依次执行以下命令创建环境并安装依赖:

conda create -n chatglm3-demo python=3.10 conda activate chatglm3-demo pip install -r requirements.txt

请注意,本项目要求 Python 3.10 或更高版本。requirements.txt(见 composite_demo/requirements.txt)声明的依赖包括:

  • huggingface_hub>=0.19.4:提供流式生成响应类型TextGenerationStreamResponse;
  • pillow>=10.1.0:用于在代码解释器模式中解码并展示模型生成的 PNG 图片;
  • pyyaml>=6.0.1:用于工具模式手动模式下解析 YAML 格式的工具定义;
  • requests>=2.31.0:内置天气工具访问外部天气服务;
  • ipykernel>=6.26.0、ipython>=8.18.1、jupyter_client>=8.6.0:为 Code Interpreter 模式提供 Jupyter 内核运行环境。

除了 Python 依赖之外,使用 Code Interpreter 模式还必须将当前环境注册为 Jupyter 内核,否则demo_ci.py无法启动代码执行后端:

ipython kernel install --name chatglm3-demo --user

该命令会把名为chatglm3-demo的 IPython 内核安装到当前用户目录,demo_ci.py中通过jupyter_client.KernelManager(kernel_name=IPYKERNEL, ...)按名字加载它(见 demo_ci.py)。

三、启动 Demo 与环境变量

安装完成后,在composite_demo目录下执行:

streamlit run main.py

命令执行后,终端会打印 Demo 的访问地址,点击即可打开页面。首次访问时程序会下载并加载模型,可能需要花费较长时间——因为默认模型来源是 Hugging Face 上的THUDM/chatglm3-6b。

如果模型已经下载到本地,或者需要调整加载方式,可以通过环境变量控制,相关取值可直接在源码中找到依据:

环境变量默认值作用(源码位置)
MODEL_PATHTHUDM/chatglm3-6b指定模型路径,可指向本地目录(client.py)
TOKENIZER_PATH与MODEL_PATH相同指定分词器路径(client.py)
PT_PATH无指定 P-Tuning v2 微调 checkpoint 目录,加载后会将prefix_encoder权重注入模型(client.py)
PRE_SEQ_LEN128P-Tuning v2 前缀序列长度(client.py)
IPYKERNELchatglm3-demo自定义 Code Interpreter 使用的 Jupyter 内核名称(demo_ci.py)

典型用法如下:

export MODEL_PATH=/path/to/model export IPYKERNEL=<kernel_name> streamlit run main.py

从源码看,模型加载统一走client.py中的HFClient(见 client.py):使用AutoTokenizer.from_pretrained(..., trust_remote_code=True)加载分词器,模型则通过AutoModel.from_pretrained(..., trust_remote_code=True, device_map="auto").eval()自动分配设备;若设置了PT_PATH且目录存在,则会以pre_seq_len=PRE_SEQ_LEN加载配置,并把 checkpoint 中transformer.prefix_encoder.前缀的状态字典装入模型。源码注释中还提示:如需使用 int4 量化模型,可在.eval()前追加.quantize(bits=4, device="cuda").cuda(),但int4 模型必须在 CUDA 上加载。get_client()被@st.cache_resource装饰,确保整个 Streamlit 会话期间模型只加载一次。

四、对话模式(Chat):用侧边栏参数精确控制生成

对话模式下,用户可以直接在左侧边栏修改生成参数来调整模型行为(参数默认值均取自 main.py):

  • top_p:取值0.0 ~ 1.0,默认0.8,步长0.01,控制核采样概率;
  • temperature:取值0.0 ~ 1.5,默认0.95,步长0.01,控制随机性;
  • repetition_penalty:取值0.0 ~ 2.0,默认1.1,步长0.01,抑制重复;
  • Output length(max_new_tokens):取值5 ~ 32000,默认256,控制最大新生成 token 数;
  • System Prompt:仅对对话模式生效的文本域,默认值为 “You are ChatGLM3, a large language model trained by Zhipu.AI. Follow the user's instructions carefully. Respond using markdown.”,可在界面中随时修改。

侧边栏还提供Clear History(清空历史)与Retry(重试)两个按钮,其中 Retry 会找到最近一条用户消息并删除其之后的历史后重新生成(见 demo_chat.py)。

对话模式的流式生成在 demo_chat.py 中实现:调用client.generate_stream(...)时传入do_sample=True及上述采样参数,并设置stop_sequences=[str(Role.USER)],即遇到<|user|>特殊 token 时停止生成;生成过程中,流式返回的每个 token 会实时通过postprocess_text清洗并渲染到页面(带▌光标闪烁效果),遇到特殊 token 则退出循环并把完整回复追加进历史。此外,client.py中的stream_chat还内置了InvalidScoreLogitsProcessor(见 client.py):一旦检测到 logits 中出现 NaN 或 Inf,就将分数清零并给索引 5 的位置赋一个大值,防止数值异常导致生成崩溃。

五、工具模式(Tool):一行装饰器扩展模型能力

工具模式是 ChatGLM3 复合 Demo 最具扩展性的部分。通过注册新工具即可增强模型能力,而注册方式极其简单:使用@register_tool装饰函数即可(详见 tool_registry.py)。

注册规则(文档 + 源码双重确认):

  • 工具名称= 函数名(func.__name__);
  • 工具描述= 函数 docstring(inspect.getdoc(func));
  • 工具参数= 函数签名中的参数,必须使用Annotated[typ, description, required]标注类型、描述与是否必填。

register_tool会校验每个参数:缺少类型标注、未使用typing.Annotated、描述不是字符串、required不是布尔值,都会抛出TypeError(见 tool_registry.py)。

官方文档给出的最小注册示例:

@register_tool def get_weather( city_name: Annotated[str, 'The name of the city to be queried', True], ) -> str: """ Get the weather for `city_name` in the following week """ ...

仓库自带的真实实现(见 tool_registry.py)在此基础上调用了公共天气服务wttr.in,解析 JSON 后返回温度、体感温度、湿度、天气描述与观测时间等字段,并对请求异常做了兜底:

@register_tool def get_weather( city_name: Annotated[str, 'The name of the city to be queried', True], ) -> str: """ Get the current weather for `city_name` """ ... resp = requests.get(f"https://wttr.in/{city_name}?format=j1") ...

除get_weather外,仓库还预置了两个演示工具:

  • random_number_generator(seed, range):按指定随机种子与整数区间生成随机数(tool_registry.py);
  • get_shell(query):在 Linux shell 中执行命令并返回标准输出(tool_registry.py),注意该工具会直接运行任意命令,仅在本地可信环境使用。

注册后的工具会同时写入两个字典:_TOOL_HOOKS[tool_name] = func用于实际调用,_TOOL_DESCRIPTIONS[tool_name] = tool_def用于生成给模型看的工具声明;get_tools()返回其深拷贝(tool_registry.py),dispatch_tool(tool_name, tool_params)则负责按名分发调用并捕获异常(tool_registry.py)。

工具模式的实际效果如下图所示——模型在对话中主动发起天气查询工具调用:

工具调用循环与特殊 token

在 demo_tool.py 中可以看到完整的工具调用循环:模型输出遇到<|assistant|>特殊 token 时切换到工具消息气泡,遇到<|observation|>时则从输出文本中提取“工具名 + 调用参数代码块”,用extract_code抓取最后的 ``` 代码块,再通过eval(code, {'tool_call': tool_call}, {})把tool_call(...)形式的调用解析为参数字典,随后调用dispatch_tool(tool, args)并弹出 spinner(“Calling tool ...”)等待执行结果;返回结果超过truncate_length(Demo 中为 1024)时会截断并追加[TRUNCATED]标记。整个循环最多迭代 5 轮,防止模型陷入无限工具调用。

手动模式(Manual mode):用 YAML 自定义工具列表

在工具模式页面中,还可以通过Manual mode开关进入手动模式(见 demo_tool.py)。在该模式下,页面会展开一个 YAML 文本域,你可以直接以 YAML 形式定义任意工具列表,文本域预填充了 OpenAI 风格的get_current_weather示例(包含parameters.properties与required字段,见 demo_tool.py):

- name: get_current_weather description: Get the current weather in a given location parameters: type: object properties: location: type: string description: The city and state, e.g. San Francisco, CA unit: type: string enum: [celsius, fahrenheit] required: - location

手动模式下工具定义通过yaml.safe_load解析(格式错误会提示 “YAML format error in tools definition”),但工具的实际输出需要你手动填写并反馈给模型——页面会显示 “Please provide tool call results below:” 提示,由人来扮演工具执行者。这适合快速验证自定义工具的声明格式,或接入尚未写进tool_registry.py的临时工具。

六、代码解释器模式(Code Interpreter):让模型写代码、跑代码、看结果

由于拥有代码执行环境,该模式下的模型能够完成更为复杂的任务,例如绘制图表、执行符号运算等。模型会根据自身对任务完成情况的理解,自动连续执行多个代码块,直到认为任务完成;因此在这一模式下,你只需要指明希望模型执行的任务即可。

代码执行后端由 demo_ci.py 中的CodeKernel类封装(demo_ci.py):

  • 构造时基于jupyter_client.KernelManager启动名为IPYKERNEL(默认chatglm3-demo)的后端内核,并通过blocking_client()建立代码客户端;
  • execute(code)提交代码后等待最多 30 秒获取 shell 消息与 IOPub 输出,轮询直到内核进入idle状态;
  • 提供execute_interactive、inspect、get_error_msg、restart、interrupt、shutdown等管理方法;
  • get_kernel()被@st.cache_resource装饰,同一会话内复用内核实例,避免反复重启。

代码执行结果由execute(code, kernel)(demo_ci.py)处理:支持text/plain文本输出与image/png图片输出两种形态——图片输出会通过b64_2_img解码为PIL.Image直接渲染在聊天界面中(demo_ci.py);文本输出超长时同样按truncate_length截断。此外该模式自带一段中文系统提示词(demo_ci.py),声明模型连接着一台不能联网的电脑、可运行 Python 代码、可处理用户上传到/mnt/data/的文件,并在出错时改进代码。

官方文档给出的经典示例是让 ChatGLM3 画一个爱心,模型自动生成绘图代码、执行并在页面中展示结果:

从 demo_ci.py 的生成循环可以看到,该模式同样以<|assistant|>、<|observation|>特殊 token 为节点驱动多轮“生成代码 → 执行 → 返回观察结果”的循环,最多迭代 5 轮;执行时页面显示 “Executing code...” 的 spinner,观察结果会以Role.OBSERVATION追加进历史,供模型在下一轮生成中参考。

七、交互细节与提示

  • 停止生成:模型生成文本时,点击页面右上角的Stop按钮可以随时打断当前流式输出;
  • 清空历史:刷新页面即可清空对话记录;侧边栏的Clear History按钮也能做到(main.py 中点击后会把prompt_text置空,各子模块检测到空输入即清空会话历史);
  • 多轮上下文:三种模式都会把对话历史以Conversation(角色 + 内容)的形式保存在st.session_state中,并通过 conversation.py 中的Role枚举映射为 ChatGLM3 的特殊 token(<|system|>、<|user|>、<|assistant|>、<|observation|>),从而保证模型理解完整的对话与工具调用脉络。

八、结语

从整体实现看,ChatGLM3 Composite Web Demo 是理解 ChatGLM3 三大多模态交互范式的绝佳入口:main.py负责把界面参数与三种模式串起来,tool_registry.py提供了极简的@register_tool工具扩展机制,demo_ci.py展示了如何把模型与 Jupyter 内核对接成可执行代码的智能体。如果你想快速体验 ChatGLM3 的对话、工具调用与代码执行能力,或在此基础上开发自己的多工具智能体界面,直接以本文为指引克隆并运行composite_demo即可——更详细的逐行实现还可以继续阅读 composite_demo 目录下的全部源码。

Enjoy!

  • 大模型
  • 人工智能
  • 微调
  • 本地部署
  • AI Agent
  • RAG

【免费下载链接】ChatGLM3

ChatGLM3 series: Open Bilingual Chat LLMs | 开源双语对话语言模型

项目地址:https://gitcode.com/gh_mirrors/ch/ChatGLM3
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/4 7:18:04

Eastman的BIM思想:从产品模型到全生命周期范式

1. 项目概述&#xff1a;一位奠基者的远去&#xff0c;一场行业范式的长跑起点“大数据之父_BIM先驱Charles (Chuck) M. Eastman逝世”——这行标题不是新闻快讯的简单堆砌&#xff0c;而是建筑信息模型&#xff08;BIM&#xff09;发展史上一座里程碑悄然倾塌的回响。当“BIM之…

作者头像 李华
网站建设 2026/10/4 7:16:18

PIC18F4680+PMP驱动MRAM:工业级数据存储方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/4 7:16:06

Codex CLI 与 IDE 插件实战:从安装配置到 Agent 协作的完整指南

1. 先搞清楚 Codex 到底是什么&#xff0c;别被名字带偏很多人第一次听到 Codex 这个词&#xff0c;脑子里蹦出来的可能是几年前那个写代码的模型&#xff0c;或者某个已经停掉的服务。现在大家嘴里说的 Codex&#xff0c;更多是指一套能跑在终端和编辑器里的智能编程助手体系&…

作者头像 李华
网站建设 2026/10/4 7:14:41

HDR后处理调色链路:从颜色空间到色调映射与LUT

如果你是被标题里“后处理”三个字吸引进来的&#xff0c;我先多说一句&#xff1a;如果你要找的是YOLO的NMS后处理流程、Hypermill五轴后处理制作&#xff0c;或者UG那边判断4轴变化后Z轴回零的代码&#xff0c;那这篇文章跟你预期的完全不是一回事。图形学语境里的后处理&…

作者头像 李华
网站建设 2026/10/4 7:13:07

OpenShell效率终端:多标签页与自动补全重构Windows命令行体验

1. 项目概述与核心价值1.1 为什么选 OpenShell&#xff1a;从“能用”到“好用”的一次升级OpenShell 并不是一个全新的概念&#xff0c;它本质上是一款可以直接替代 Windows 默认命令行工具&#xff08;cmd.exe 以及旧版 Windows PowerShell&#xff09;的现代化终端外壳程序。…

作者头像 李华
网站建设 2026/10/4 7:12:40

插件加载失败排查全指南:破解web boot entries did not activate

如果你在日志里见过failed to load plugins web boot: 2 entries did not activate这种报错&#xff0c;多半是正在做插件化改造的 Web 应用&#xff0c;或者刚接手一套带插件机制的工程。这类问题的奇怪之处在于&#xff1a;应用通常能启动&#xff0c;功能也能用&#xff0c;…

作者头像 李华