- 大模型
- 人工智能
- 微调
- 本地部署
- AI Agent
- RAG
【免费下载链接】ChatGLM3
ChatGLM3 series: Open Bilingual Chat LLMs | 开源双语对话语言模型
本文以仓库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.py | Streamlit 入口,负责侧边栏参数、模式切换与三个子模块的调度 |
| 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_PATH | THUDM/chatglm3-6b | 指定模型路径,可指向本地目录(client.py) |
TOKENIZER_PATH | 与MODEL_PATH相同 | 指定分词器路径(client.py) |
PT_PATH | 无 | 指定 P-Tuning v2 微调 checkpoint 目录,加载后会将prefix_encoder权重注入模型(client.py) |
PRE_SEQ_LEN | 128 | P-Tuning v2 前缀序列长度(client.py) |
IPYKERNEL | chatglm3-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 | 开源双语对话语言模型
相关推荐
Beads Docker部署:容器化你的AI任务跟踪系统
Beads Docker部署:容器化你的AI任务跟踪系统 Beads作为一款强大的AI任务跟踪系统,能为你的开发流程提供智能记忆升级。通过Docker容器化部署
前端UI组件Remotion 文档交互式 Demo 系统:从组件到 <Demo> 注册的完整实践
Remotion 文档交互式 Demo 系统:从组件到 <Demo 注册的完整实践 本文以 Remotion 仓库中的技能文档 .agents/skills/d
音视频AI 应用前端Spring Boot Admin 客户端注册完全指南:三种注册方式与源码级实现解析
Spring Boot Admin 客户端注册完全指南:三种注册方式与源码级实现解析 Spring Boot Admin 为 Spring Boot 应用提供管
后端可观测性指标监控监控大盘MCP 服务
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考