Ollama平台ChatGLM3-6B-128K应用:支持工具调用的Agent系统搭建
Ollama平台ChatGLM3-6B-128K应用:支持工具调用的Agent系统搭建
你是不是也遇到过这样的场景?想让AI帮你查一下天气,它却只会说“我无法访问实时数据”;想让AI帮你分析一个Excel文件,它却只能对着你粘贴的文本干瞪眼。传统的对话模型就像一个知识渊博但手脚被束缚的学者,知道很多,但做不了具体的事。
今天,我们要聊的ChatGLM3-6B-128K,就是一个被“松绑”的学者。它不仅能和你聊天,还能在得到你允许后,去调用外部的工具,比如搜索引擎、计算器、数据库,真正帮你“动手”解决问题。更厉害的是,它拥有处理长达128K上下文的能力,意味着你可以丢给它一整本小说或一份冗长的技术文档,它都能理清头绪。
这篇文章,我就手把手带你,在Ollama这个轻量级平台上,把ChatGLM3-6B-128K部署起来,并重点演示如何搭建一个能调用外部工具的智能体(Agent)系统。你会发现,让AI成为你的全能助手,其实并不复杂。
1. 认识我们的主角:ChatGLM3-6B-128K
在开始动手之前,我们得先搞清楚手里这把“瑞士军刀”到底有多锋利。ChatGLM3-6B-128K并非凭空出现,它是ChatGLM3系列中的“长文本特化版”。
1.1 核心特性:长文本与多功能
它的核心能力可以概括为两点:“看得长” 和 “干得多”。
- “看得长”- 128K上下文:普通模型处理几千字就吃力了,而它能轻松应对约20万汉字(128K tokens)的文本。无论是分析长篇报告、总结学术论文,还是进行超长对话,它都能保持连贯的理解,不会“忘记”开头说了什么。官方建议,如果你的任务上下文通常超过8K,就选它;否则,标准的ChatGLM3-6B可能更高效。
- “干得多”- 原生工具调用与Agent能力:这是ChatGLM3系列最大的升级。它不再只是一个聊天机器人,而是一个智能体(Agent) 的核心大脑。它内置了对“工具调用(Function Call)”和“代码执行(Code Interpreter)”的原生支持。这意味着你可以定义一些工具(比如“查询天气”、“计算器”),AI在对话中会判断是否需要使用这些工具,并生成规范的调用请求,由你的程序去执行,最后把结果返回给它,它再组织语言回答你。这就实现了从“知道”到“做到”的跨越。
1.2 为什么选择Ollama平台?
你可能听说过很多部署方式,比如原生的Transformers库、FastAPI封装等。Ollama的优势在于极致的简单。
- 一键部署:无需关心复杂的Python环境、CUDA版本冲突,一条命令就能拉取和运行模型。
- 开箱即用的API:Ollama直接提供了类OpenAI的API接口,你的应用程序可以通过简单的HTTP请求与模型交互,大大降低了集成难度。
- 资源管理友好:方便地查看模型列表、卸载模型,管理起来非常直观。
简单来说,Ollama让部署和使用大模型变得像安装手机App一样简单。接下来,我们就进入实战环节。
2. 第一步:在Ollama中部署ChatGLM3-6B-128K
虽然官方Ollama库可能还未直接收录chatglm3-6b-128k这个模型,但社区已经贡献了优秀的版本。我们将使用一个广受好评的第三方模型文件。
打开你的终端(命令行),执行以下命令:
ollama run entropyyue/chatglm3
是的,就这么简单。这条命令会完成所有工作:
- 拉取模型:自动从Ollama仓库下载名为
entropyyue/chatglm3的模型(这个镜像通常基于最新的ChatGLM3-6B-128K构建)。 - 启动交互式对话:下载完成后,你会直接进入一个对话界面,可以开始测试。
首次运行可能会看到类似这样的输出:
pulling manifest
pulling xxxxxxxxxx... 100%
pulling yyyyyyyyyy... 100%
verifying sha256 digest
writing manifest
success
>>> Send a message (/? for help)
看到 >>> 提示符,就说明模型已经加载成功,正在等待你的输入。你可以先简单测试一下:
>>> 你好,请介绍一下你自己。
如果模型流畅地回应了,恭喜你,部署成功!你可以按 Ctrl+D 退出交互模式。模型会继续在后台运行,提供服务。
3. 核心实战:构建一个能调用工具的Agent系统
现在,模型已经跑起来了,但它还只是一个“裸”的模型。我们要为它装配“手脚”(工具),并建立一个调度系统(Agent逻辑)。这里,我们使用Python和Ollama的API来实现。
3.1 设计我们的工具
我们先定义两个简单的工具,让AI学会使用:
- 获取天气工具:模拟查询指定城市的天气。
- 计算器工具:执行数学计算。
# tool_functions.py
def get_weather(city: str) -> str:
"""
模拟获取指定城市的天气信息。
参数:
city (str): 城市名称,例如“北京”、“上海”。
返回:
str: 模拟的天气信息字符串。
"""
# 这里模拟一个天气查询结果,真实场景可以调用天气API
weather_data = {
"北京": "晴,15~25℃,西北风2级",
"上海": "多云,18~28℃,东南风3级",
"广州": "阵雨,22~30℃,南风1级",
"深圳": "阴,23~31℃,微风"
}
return weather_data.get(city, f"未找到{city}的天气信息。")
def calculator(expression: str) -> str:
"""
执行数学表达式计算(使用eval,注意安全)。
仅用于演示,生产环境需严格过滤输入。
参数:
expression (str): 数学表达式,如“3 + 5 * 2”。
返回:
str: 计算结果或错误信息。
"""
try:
# 警告:实际应用中应对expression做严格的安全检查,避免代码注入
result = eval(expression)
return str(result)
except Exception as e:
return f"计算错误:{e}"
3.2 构建Agent调度逻辑
Agent的核心是循环:理解用户请求 -> 判断是否需要调用工具 -> 执行工具 -> 将结果返回给模型 -> 生成最终回答。
# agent_system.py
import requests
import json
import re
# Ollama API的基础地址,假设Ollama在本地默认端口运行
OLLAMA_API_BASE = "http://localhost:11434/api"
def chat_with_ollama(messages, model="entropyyue/chatglm3"):
"""
通过Ollama的API与模型对话。
参数:
messages (list): 对话历史消息列表,格式同OpenAI API。
model (str): 模型名称。
返回:
str: 模型的回复内容。
"""
url = f"{OLLAMA_API_BASE}/chat"
payload = {
"model": model,
"messages": messages,
"stream": False # 为简化示例,关闭流式输出
}
try:
response = requests.post(url, json=payload)
response.raise_for_status()
return response.json()["message"]["content"]
except requests.exceptions.RequestException as e:
return f"API调用失败:{e}"
def parse_tool_call(model_response):
"""
尝试从模型回复中解析工具调用请求。
ChatGLM3的工具调用格式通常包含特定的JSON标记,如 ```json ... ```。
参数:
model_response (str): 模型的回复文本。
返回:
dict or None: 解析出的工具调用信息(名称和参数),如果无工具调用则返回None。
"""
# 查找JSON代码块
pattern = r'```json\s*(.*?)\s*```'
match = re.search(pattern, model_response, re.DOTALL)
if match:
json_str = match.group(1)
try:
tool_call = json.loads(json_str)
# 检查是否符合工具调用结构
if "name" in tool_call and "arguments" in tool_call:
return tool_call
except json.JSONDecodeError:
pass
return None
def run_agent(user_query, max_turns=5):
"""
运行一个简单的单轮工具调用Agent。
参数:
user_query (str): 用户的初始问题。
max_turns (int): 最大交互轮次(防止死循环)。
返回:
str: Agent的最终回答。
"""
from tool_functions import get_weather, calculator # 导入之前定义的工具
# 定义可供模型调用的工具列表(描述很重要,模型靠这个理解工具功能)
available_tools = [
{
"name": "get_weather",
"description": "获取指定城市的当前天气信息。",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名称,如‘北京’、‘上海’。"}
},
"required": ["city"]
}
},
{
"name": "calculator",
"description": "执行一个数学表达式并返回计算结果。",
"parameters": {
"type": "object",
"properties": {
"expression": {"type": "string", "description": "数学表达式,如‘3 + 5 * 2’。"}
},
"required": ["expression"]
}
}
]
# 初始化对话历史,将工具描述作为系统提示告诉模型
system_prompt = f"""你是一个有帮助的助手,可以调用工具来解决问题。
你可以使用的工具如下:
{json.dumps(available_tools, ensure_ascii=False, indent=2)}
当你需要调用工具时,请严格按照以下格式在JSON代码块中回复:
```json
{{"name": "工具名称", "arguments": {{"参数名": "参数值"}}}}
我会执行工具并将结果告诉你。"""
messages = [{"role": "system", "content": system_prompt},
{"role": "user", "content": user_query}]
for turn in range(max_turns):
# 1. 将当前对话历史发送给模型,获取回复
model_reply = chat_with_ollama(messages)
print(f"\n[模型回复-第{turn+1}轮]:\n{model_reply}")
# 2. 尝试解析模型回复中是否包含工具调用
tool_call = parse_tool_call(model_reply)
if not tool_call:
# 如果没有工具调用,则当前回复即为最终答案
final_answer = model_reply
# 清理可能残留的JSON代码块标记
final_answer = re.sub(r'```json\s*.*?\s*```', '', final_answer, flags=re.DOTALL).strip()
return final_answer
# 3. 执行工具调用
tool_name = tool_call["name"]
tool_args = tool_call["arguments"]
print(f"[检测到工具调用]: {tool_name},参数:{tool_args}")
tool_result = None
if tool_name == "get_weather":
tool_result = get_weather(**tool_args)
elif tool_name == "calculator":
tool_result = calculator(**tool_args)
else:
tool_result = f"错误:未知工具 '{tool_name}'。"
print(f"[工具执行结果]: {tool_result}")
# 4. 将工具执行结果作为新消息追加到对话历史,让模型进行下一步
# 首先,将模型刚才的回复(包含工具调用)加入历史
messages.append({"role": "assistant", "content": model_reply})
# 然后,将工具执行结果作为“用户”消息或“工具”角色消息加入(这里简化处理)
messages.append({"role": "user", "content": f"工具`{tool_name}`的返回结果是:{tool_result}"})
return "对话轮次过多,可能陷入循环。"
if name == "main": # 测试几个例子 test_queries = [ "北京今天天气怎么样?", "帮我计算一下(15 + 7) * 3 等于多少?", "先告诉我上海的天气,然后计算一下如果气温是25度,换算成华氏度是多少?(公式:F = C × 9/5 + 32)" ]
for query in test_queries:
print(f"\n{'='*50}")
print(f"用户问题:{query}")
print(f"{'='*50}")
answer = run_agent(query)
print(f"\n[Agent最终答案]:\n{answer}")
### 3.3 运行与效果解读
运行上面的`agent_system.py`脚本。你需要确保Ollama服务正在运行(终端里执行 `ollama serve` 或模型已在后台)。
**你会看到类似这样的交互过程:**
对于问题 **“北京今天天气怎么样?”**:
1. 模型回复中会包含一个JSON代码块,请求调用 `get_weather` 工具,参数为 `{"city": "北京"}`。
2. 我们的程序捕捉到这个请求,执行 `get_weather("北京")`,得到模拟天气数据。
3. 程序将天气结果反馈给模型。
4. 模型生成最终的自然语言回答:“北京今天的天气是晴,15~25℃,西北风2级。”
对于更复杂的第三个问题,模型可能会展示**多轮工具调用**的能力:先调用天气工具获取上海温度(假设25℃),再调用计算器工具计算华氏度(25 * 9/5 + 32 = 77°F)。
## 4. 深入探索:让Agent更强大
我们搭建了一个最基础的Agent框架。要让它真正实用,还可以从以下几个方面深化:
### 4.1 集成更多真实工具
将模拟工具替换为真实的API:
* **网络搜索**:集成SerperAPI、Google Search API。
* **数据查询**:连接数据库(MySQL、PostgreSQL)或调用企业内部API。
* **文件操作**:读取本地PDF、Word、Excel文件进行分析(需结合RAG技术)。
* **软件控制**:发送邮件、生成图表、操作办公软件。
### 4.2 优化提示工程与工具描述
模型能否正确调用工具,很大程度上取决于**系统提示(System Prompt)** 中对工具的**描述是否清晰准确**。
* **描述要具体**:明确工具的用途、输入参数格式、输出是什么。
* **提供示例**:在系统提示中给出1-2个工具调用的例子,效果会显著提升。
* **指定格式**:就像我们做的,严格要求模型以特定格式(如JSON代码块)返回工具调用请求。
### 4.3 处理复杂对话与长上下文
ChatGLM3-6B-128K的128K能力在此大放异彩。
* **长文档摘要**:将整个技术手册、法律合同丢给Agent,让它先总结要点,再根据你的具体问题定位细节。
* **多轮复杂任务**:用户的需求可能分多步。“帮我规划一个三天的北京旅游行程,查一下故宫下周一的门票价格和天气,然后估算一下总花费。” Agent需要分解任务,依次调用行程生成、票务查询、天气查询、计算器等工具,并在整个长对话中记住所有上下文。
### 4.4 错误处理与稳定性
生产级系统需要更健壮:
* **工具调用失败**:网络超时、API限流、参数错误等,需要有重试或降级方案。
* **模型输出解析失败**:模型可能不按预定格式回复,需要设计更鲁棒的解析器或让模型重试。
* **超长上下文管理**:虽然支持128K,但无限堆积历史消息会降低效率。需要设计策略,选择性保留或总结关键历史信息。
## 5. 总结
通过本文的实践,我们完成了一件很酷的事:**在个人电脑上,用Ollama轻松部署了强大的ChatGLM3-6B-128K模型,并为其赋予了调用外部工具的能力,构建了一个智能体系统的雏形。**
我们回顾一下关键步骤和收获:
1. **部署极简**:Ollama的 `ollama run` 命令让模型部署变得毫无门槛。
2. **能力解锁**:ChatGLM3原生的工具调用功能,是构建实用AI Agent的基石。我们通过定义清晰的工具描述和解析模型响应,实现了“思考”与“行动”的闭环。
3. **框架搭建**:我们实现了一个简单的Agent调度循环(感知->规划->行动->观察),这是所有复杂Agent系统的基本原理。
4. **潜力巨大**:这个基础框架可以无限扩展。接入真实API、处理长文档、管理复杂对话流,就能开发出真正能解决实际问题的AI助手。
从“聊天机器人”到“智能执行体”,ChatGLM3-6B-128K与Ollama的组合,为我们打开了一扇低成本、高效率构建个性化AI应用的大门。无论是用于个人效率提升,还是作为更复杂产品的核心引擎,这都是一个绝佳的起点。
现在,你可以尝试为你的Agent添加第一个真实世界的工具了,比如查询实时股价、翻译大段文档,或者管理你的待办事项列表。动手试试看,感受AI从“知道”到“做到”的魅力吧。
---
> **获取更多AI镜像**
>
> 想探索更多AI镜像和应用场景?访问 [CSDN星图镜像广场](https://ai.csdn.net/?utm_source=mirror_blog_end),提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐

所有评论(0)