- 大模型
- AI Agent
- 模型推理服务
- 微调
- 对话系统
【免费下载链接】ChatGLM3
ChatGLM3 series: Open Bilingual Chat LLMs | 开源双语对话语言模型
ChatGLM3 的 composite_demo 是基于 Streamlit 构建的一体化 Web 交互界面,它将对话、工具调用与代码解释三大能力封装在同一个页面中,开发者只需一条命令即可启动。本文将基于 composite_demo/README.md 的官方说明,并结合 composite_demo 目录下的完整源码,系统讲解环境安装、模型加载、三种模式的原理与实操,以及如何通过注册新工具为模型扩展能力,读完即可在本地跑通一个具备 Agent 雏形的 ChatGLM3 演示应用。
一、Demo 概览:一个页面,三种模式
ChatGLM3 Web Demo 提供了三种互不冲突的使用模式,用户可在页面顶部的模式选择器中随时切换(源码见 main.py 中的Mode枚举):
- Chat(对话模式):与模型进行常规多轮对话,可在侧边栏实时调整采样参数与 System Prompt;
- Tool(工具模式):模型除对话外,还能按需调用已注册的工具(如查天气、跑命令)完成操作;
- Code Interpreter(代码解释器模式):模型在 Jupyter 内核环境中实际执行 Python 代码并获取结果,可自动连续执行多个代码块以完成绘图、符号运算等复杂任务。
下图是 Demo 的完整主界面,可以看到三种模式的切换入口、侧边栏参数区与底部对话输入框:
二、环境安装
2.1 创建 Conda 环境并安装依赖
官方文档推荐使用 [Conda] 管理 Python 环境(Conda 为外部工具,实际使用请以其官方文档为准)。依次执行以下命令:
conda create -n chatglm3-demo python=3.10 conda activate chatglm3-demo pip install -r requirements.txt注意:本项目要求Python 3.10 或更高版本。
composite_demo/requirements.txt 中的完整依赖清单如下:
huggingface_hub>=0.19.4 pillow>=10.1.0 pyyaml>=6.0.1 requests>=2.31.0 ipykernel>=6.26.0 ipython>=8.18.1 jupyter_client>=8.6.0各依赖的用途分别是:huggingface_hub负责从 Hugging Face Hub 拉取模型与分词器(client.py 中导入其流式响应类型);pillow用于展示代码解释器输出的图片结果;pyyaml用于工具模式的 YAML 解析(demo_tool.py);requests被内置天气工具用于调用天气接口;ipykernel、ipython、jupyter_client则是代码解释器模式启动 Jupyter 内核的基础。
2.2 安装 Jupyter 内核
代码解释器模式依赖 Jupyter 执行环境,因此在安装依赖后还需要把当前 conda 环境注册为 Jupyter 内核:
ipython kernel install --name chatglm3-demo --user这里的chatglm3-demo是内核名称,demo_ci.py 中的默认值IPYKERNEL = os.environ.get('IPYKERNEL', 'chatglm3-demo')与之对应,也就是说:内核名称必须与上述命令注册的名称一致,否则代码解释器模式将无法启动内核。
三、启动 Demo
在项目根目录下运行:
streamlit run main.py启动成功后命令行会输出 Demo 的访问地址(默认为http://localhost:8501),点击即可打开页面。首次访问时需要下载并加载模型,根据网络状况可能需要较长时间。
3.1 关键环境变量
如果模型已经下载到本地,可通过环境变量指定本地路径,避免重复下载。以下是 client.py 中定义的全部可配置项:
| 环境变量 | 默认值 | 作用 |
|---|---|---|
MODEL_PATH | THUDM/chatglm3-6b | 模型路径(Hugging Face 仓库名或本地目录) |
TOKENIZER_PATH | 同MODEL_PATH | 分词器路径,可与模型路径分离 |
PT_PATH | 无 | P-Tuning v2 微调 checkpoint 目录路径 |
PRE_SEQ_LEN | 128 | P-Tuning v2 前缀序列长度 |
IPYKERNEL | chatglm3-demo | 代码解释器使用的 Jupyter 内核名称 |
官方文档给出的两种典型用法:
# 从本地加载已下载的模型 export MODEL_PATH=/path/to/model # 自定义 Jupyter 内核 export IPYKERNEL=<kernel_name>3.2 模型加载的实现细节
模型加载逻辑封装在 client.py 的HFClient中,并通过@st.cache_resource(client.py)做了缓存,保证 Streamlit 脚本重跑时不会重复加载模型:
- 普通场景下,使用
AutoModel.from_pretrained(MODEL_PATH, trust_remote_code=True, device_map="auto")加载,并切换为推理模式.eval();ChatGLM3 依赖远程代码执行,因此trust_remote_code=True是必选项; - 当设置了
PT_PATH且路径存在时,会以pre_seq_len=PRE_SEQ_LEN的配置加载模型,并把 P-Tuning checkpoint 中的transformer.prefix_encoder.权重恢复到模型前缀编码器中,从而支持加载微调后的模型; - 源码注释中还提示:若使用 int4 量化模型,需在
.eval()前追加.quantize(bits=4, device="cuda").cuda()并去掉device_map="auto",且 int4 模型必须在 CUDA 上加载。
四、对话模式(Chat):侧边栏参数与流式输出
对话模式下,用户可以直接在侧边栏修改以下参数来调整模型行为(对应 main.py 的控件定义):
| 参数 | 取值范围 | 默认值 | 说明 |
|---|---|---|---|
top_p | 0.0 ~ 1.0,步长 0.01 | 0.8 | 核采样概率阈值 |
temperature | 0.0 ~ 1.5,步长 0.01 | 0.95 | 采样温度,越高越随机 |
repetition_penalty | 0.0 ~ 2.0,步长 0.01 | 1.1 | 重复惩罚系数 |
Output length(max_new_tokens) | 5 ~ 32000 | 256 | 生成的最大新 token 数 |
| System Prompt | 多行文本 | ChatGLM3 官方默认提示词 | 仅对对话模式生效 |
其中默认的 System Prompt 定义在 main.py:
DEFAULT_SYSTEM_PROMPT = ''' You are ChatGLM3, a large language model trained by Zhipu.AI. Follow the user's instructions carefully. Respond using markdown. '''.strip()通过修改 System Prompt 可以显著改变模型的回复风格。例如在侧边栏将 System Prompt 设置为“只用 emoji 回复”,模型便会在后续对话中严格遵守:
4.1 流式生成的底层机制
对话模式的主逻辑位于 demo_chat.py,其核心调用链为:
client.generate_stream(system_prompt, tools=None, history, ...)发起流式请求,并设置stop_sequences=[str(Role.USER)],即遇到<|user|>特殊 token 时停止生成;- client.py 中的
generate_stream将历史会话转换为system/user/assistant角色结构,再交由stream_chat逐 token 产出; stream_chat(client.py)内部使用自定义的InvalidScoreLogitsProcessor将 NaN/Inf 分数清零并置为token 5,同时把eos_token_id扩展为[eos, <|user|>, <|observation|>],保证模型在合适位置自然结束;- 前端用
postprocess_text(conversation.py)清理输出中的特殊 token,并通过markdown_placeholder.markdown(output_text + '▌')实现打字机式的流式渲染效果。
另外,conversation.py 中的Role枚举将角色映射为 ChatGLM3 的特殊 token(<|system|>、<|user|>、<|assistant|>、<|observation|>),这是三种模式统一处理对话状态的基础。
五、工具模式(Tool):零成本注册新工具
工具模式是 ChatGLM3 Demo 最具扩展性的部分。只需在 tool_registry.py 中注册新工具,就能增强模型的能力,无需修改页面逻辑。
5.1 使用 @register_tool 注册工具
注册一个工具只需两步:
- 给函数加上
@register_tool装饰器; - 按约定写好 docstring 和带
Annotated标注的参数。
官方文档以get_weather为例给出模板:
@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 """ ...声明规则如下:
- 函数名= 工具名(模型调用时使用的标识符);
- 函数 docstring= 工具说明,会被模型读取以决定何时调用该工具;
- 参数使用
Annotated[类型, 描述, 是否必填]三元组标注,其中描述必须是字符串、必填标志必须是布尔值。
5.2 注册机制的源码实现
tool_registry.py 中的register_tool通过inspect反射机制自动完成工具声明:
- 以
func.__name__作为工具名,inspect.getdoc(func).strip()作为工具描述; - 遍历
inspect.signature(func).parameters,校验每个参数必须带有typing.Annotated注解,否则抛出TypeError; - 从注解中解析出
typ(类型名)、description(描述)和required(是否必填),组装成统一的工具定义字典; - 将函数句柄存入
_TOOL_HOOKS、将工具定义存入_TOOL_DESCRIPTIONS,供后续调用与展示使用。
仓库自带了三个可直接运行的示例工具(tool_registry.py):random_number_generator(按种子与范围生成随机数)、get_weather(通过公开天气接口查询城市天气)、get_shell(在本地 Linux shell 中执行命令并返回输出,是天然的本地 Agent 能力示例)。
5.3 工具调用的完整闭环
工具模式的主逻辑位于 demo_tool.py,其执行流程由特殊 token 驱动,形成“提问 → 模型声明工具 → 执行工具 → 反馈结果 → 模型总结”的闭环:
- 模型生成以
<|assistant|>结束的文本时,表示即将发起工具调用; - 模型输出工具名与参数 JSON,随后生成
<|observation|>特殊 token; - Demo 通过
extract_code从输出中提取参数代码块,用eval解析参数,并调用dispatch_tool(tool, args)(tool_registry.py)执行对应函数; - 工具返回值被包装为
Role.OBSERVATION对话追加到历史,若结果超过truncate_length(默认 1024)则截断并追加[TRUNCATED]标记; - 整个“生成-调用-反馈”循环最多执行 5 轮(
for _ in range(5)),模型据此继续推理直至完成回答。
下图展示了模型在用户询问“巴黎天气”后,自主选择get_weather工具、传入城市参数、读取观测数据并组织成自然语言回答的完整过程:
5.4 Manual mode:用 YAML 手动指定工具
除了自动读取tool_registry.py中注册的工具,页面还提供Manual mode(手动模式)开关(demo_tool.py)。开启后,可以:
- 在一个文本框中直接以 YAML 格式编写工具列表,Demo 通过
yaml.safe_load解析(解析失败会提示YAML format error in tools definition); - 预填的
EXAMPLE_TOOL是一个符合 OpenAI 风格函数声明 schema 的天气工具示例(demo_tool.py); - 在该模式下,工具不会自动执行,Demo 会提示
Please provide tool call results below:,需要用户手动把工具输出粘贴反馈给模型。
六、代码解释器模式(Code Interpreter):让模型真正“动手”
代码解释器模式是三种模式中能力上限最高的:模型拥有真实的代码执行环境,可以完成绘图、符号运算等复杂任务,并且会根据对任务完成情况的理解自动连续执行多个代码块,直到任务完成。因此,这一模式下只需指明希望模型执行的任务即可,例如“用 Python 画一个爱心”:
6.1 专属的 System Prompt
代码解释器模式有独立的中文 System Prompt(demo_ci.py),内容为:模型名为 ChatGLM、连接着一台不能联网的电脑、可通过运行 Python 代码完成任务并改进报错代码、可处理用户上传的文件(默认存储路径/mnt/data/)。
6.2 基于 Jupyter 的执行内核
该模式的核心是 demo_ci.py 中实现的CodeKernel类,它封装了jupyter_client的完整生命周期:
__init__:创建KernelManager,以IPYKERNEL环境变量指定的内核启动后端,并通过blocking_client()建立阻塞式通信通道;execute:提交代码执行,轮询 iopub 消息直到执行状态回到idle,返回 shell 消息与输出内容;- 配套提供
execute_interactive、inspect、shutdown、restart、interrupt、is_alive等内核管理方法; get_kernel()同样以@st.cache_resource缓存,保证整个会话复用同一个内核实例。
6.3 执行结果与图片回显
执行后的结果解析在execute函数(demo_ci.py):
- 输出含
text/plain时按文本返回; - 输出含
image/png时,通过b64_2_img将 base64 解码为PIL.Image对象,在对话中以图片形式展示(Conversation数据类中的image字段专门承载该结果,见 conversation.py); - 执行超时返回
Timed out,出错则通过clean_ansi_codes清洗终端转义码后展示 traceback; - 与工具模式一致,文本结果超过
truncate_length时同样会被截断。
生成流程同样由<|assistant|>、<|observation|>特殊 token 驱动,最多循环 5 轮(demo_ci.py),因此模型可以“写代码 → 看报错 → 改代码 → 再看结果”地自主迭代,直到任务完成。
七、使用技巧与注意事项
官方文档额外总结了两条高频使用技巧:
- 打断生成:模型生成文本时,可点击页面右上角的
Stop按钮随时打断; - 清空对话:刷新页面即可清空当前对话记录;侧边栏还提供了
Clear History按钮与Retry按钮(main.py),其中Retry会回溯到最近一次用户提问并重新生成回答(三种模式均实现了该逻辑)。
此外,从源码可以进一步确认几个易踩坑的点:
- 首次运行会从 Hugging Face 下载模型,请确保网络可达,或提前用
MODEL_PATH指向本地模型目录; - 代码解释器模式必须预先执行
ipython kernel install --name chatglm3-demo --user,且内核名要与IPYKERNEL(或默认值chatglm3-demo)一致; - 工具的
Annotated注解格式必须严格遵循“类型、描述字符串、布尔必填”三要素,否则注册时会直接抛出TypeError; - 自定义工具时建议对参数做运行时类型校验(参考内置工具的实现),异常会以 traceback 形式返回给模型,帮助其自我修正。
八、总结
composite_demo 将 ChatGLM3 的三种核心能力浓缩进一个 Streamlit 页面:对话模式提供了灵活的参数调节与流式体验;工具模式通过@register_tool装饰器实现了声明式工具扩展,配合 Manual mode 的 YAML 配置即可快速验证自定义工具;代码解释器模式则借助 Jupyter 内核让模型具备了“写代码、跑代码、看结果、再改进”的闭环执行能力。理解 main.py 的模式分发、client.py 的流式客户端、tool_registry.py 的注册机制以及 demo_ci.py 的内核封装,是进一步基于这套框架开发 Agent 应用、接入私有工具或微调模型演示的起点。
- 大模型
- AI Agent
- 模型推理服务
- 微调
- 对话系统
【免费下载链接】ChatGLM3
ChatGLM3 series: Open Bilingual Chat LLMs | 开源双语对话语言模型
相关推荐
ChatGLM3 三合一 Web Demo 实战指南:对话、工具调用与代码解释器模式详解
ChatGLM3 三合一 Web Demo 实战指南:对话、工具调用与代码解释器模式详解 本文以开源仓库 composite_demo 目录下的 README.
大模型人工智能微调本地部署AI AgentRAGChatGLM3 Composite Web Demo 实战指南:三种交互模式、工具注册与代码解释器的完整解析
ChatGLM3 Composite Web Demo 实战指南:三种交互模式、工具注册与代码解释器的完整解析 本文以仓库 composite_demo 目录下
大模型人工智能微调本地部署AI AgentRAGChatGLM3 Chat Format 对话格式规范:多轮对话、工具调用与代码执行全解析
ChatGLM3 Chat Format 对话格式规范:多轮对话、工具调用与代码执行全解析 导读 本文基于 ChatGLM3 官方 PROMPT_en.md 文
大模型人工智能微调本地部署AI AgentRAG
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考