ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

大模型应用开发实战:智谱GLM的Function Calling与RAG落地指南

大模型应用开发实战:智谱GLM的Function Calling与RAG落地指南 过去一段时间大模型圈子里关于智谱AI的讨论热度很高各种解读集中在市场端和资本端。这篇文章不打算评价股价涨跌也不把“市值波动”当作新闻素材再复述一遍。更值得技术人关注的是唐杰教授公开提到“走了弯路”之后我们能不能借这个复盘信号重新审视大模型从技术选型到工程落地的完整链路。对AI应用开发者来说“走了弯路”这四个字并不陌生。模型能力很强但业务链路跟不上API调通了但评测、监控、成本治理没跟上Agent 能跑起来但工具调用一多就失控。这些都是典型的“弯路”。本文以智谱AI及其 GLM 模型生态为主线拆解大模型应用开发中容易被忽视的技术决策、代码细节、运维要点和排错思路。读完本文你可以掌握大模型应用的基本技术路线判断、开放平台 API 的接入方法、Function Calling 与 RAG 的落地写法、常见坑点排查、以及上线后的评测和成本治理思路。1. 背景与核心概念为什么“走了弯路”值得复盘1.1 “走了弯路”的技术视角先说概念。智谱AI是国内较早推进大模型研发的技术团队之一GLM 系列模型也是国内大模型生态里非常有代表性的一条技术路线。“走了弯路”这句话出现在公开技术复盘语境中通常不是说模型完全失败而是指投入资源的方向与真实市场需求出现了错位或者在产品化链路中补课补得比较辛苦。從技术视角来看一类典型的“弯路”是过度追求模型单一指标忽略了“模型能力到业务价值”之间的转化层。比如模型推理能力强但缺少稳定的结构化输出业务无法直接消费。多模态能力有了但离线批处理场景比实时交互场景更急迫。Agent 一直在做 demo却没有把工具调用、权限校验、人工审核串成闭环。这些都不是智谱AI独有的问题整个行业都面临同样考验。复盘的意义就在于把教训沉淀成一套可复用的工程方法。1.2 大模型落地的核心链条一个面向业务的大模型应用通常由这几层组成底座模型。API 或 MaaS 服务。应用编排层Prompt、工具调用、RAG。业务接入层接口、鉴权、数据。评测与监控体系。很多团队在 1 和 2 上投入很多精力却低估了 3、4、5 的工作量。结果就是 demo 很吸引人上线后效果不稳定、成本失控、问题不可复现。本文后续内容就是按这条链路逐层展开。2. 技术路线三岔路口底座模型、对齐与 Agent2.1 底座模型一味堆参数不是唯一答案大模型早期竞赛的核心指标是“参数量足够大、榜单分数足够高”。但到了真实业务环境模型能力只是其中一个变量。一个实际项目里你还要关心模型是否支持较长的上下文窗口。是否有不同规格的版本能在延迟和效果之间做折中。是否支持私有化部署、微调或其他定制方式。调用成本和配额是否可控。智谱AI 的 GLM 系列给开发者提供了不同规格的模型选择。按团队实际业务需要选型思路通常是这样通用对话、文本生成用基础对话模型即可。需要视觉理解能力选择多模态模型。需要复杂工具调度优先考虑具备 Function Calling 能力的模型版本。这里要提醒一句具体模型 ID 和可用范围会随开放平台调整接入时以官方控制台展示为准。选型的第一原则不是“越强越好”而是“够用且可维护”。2.2 对齐与工具使用Function Calling 的工程价值如果模型只能聊天它很难接进业务流程。真正让大模型产生工程价值的关键能力之一是 Function Calling。Function Calling也叫函数调用是指模型在对话过程中判断“我需要调用某个外部工具”然后输出一段结构化参数由程序执行真实业务逻辑再把结果回传给模型。这个能力解决了三个问题模型不擅长计算那就让它调用计算器。模型没有实时数据那就调用查询接口。模型需要修改系统状态那就通过代码触发而不是直接生成 SQL 或指令。很多团队“走了弯路”不是因为不会写 Prompt而是没有意识到要让模型稳定工作在业务流程里必须设计清晰的工具层。2.3 Agent 与多模态业务闭环的前提再往后是 Agent。Agent 可以看成“模型 工具 循环决策”的组合。一个成熟的 Agent 应用至少要解决任务拆解把用户目标拆成多个子任务。工具选择每个子任务用哪个工具。结果合并把多个工具结果整合成最终回答。失败处理工具异常时如何重试、降级或请求用户确认。多模态则对应更丰富的输入输出形态。视频理解、图像分析、语音交互都能扩展应用场景但场景越多评测和故障面也越广。建议团队先从一个模态打透再逐步扩展。3. 环境准备与版本说明3.1 账号与密钥准备动手写代码前先完成账号与密钥准备注册智谱AI开放平台账号。完成实名认证。在控制台创建 API Key。把 API Key 保存到本地环境变量不要硬编码到源码。密钥管理后续在最佳实践章节还会展开。3.2 开发依赖与项目结构本文示例以 Python 为例建议使用 Python 3.9 及以上版本。依赖清单如下# requirements.txt openai1.30.0 fastapi0.115.0 uvicorn[standard]0.30.0 python-dotenv1.0.0 requests2.31.0安装命令pip install -r requirements.txt需要说明的是智谱AI 开放平台提供了 OpenAI 兼容的接口路径因此可以直接用 openai SDK 访问。如果你更习惯官方 SDK也可以到官方文档查看 zhipuai 相关包的导入方式。示例代码如下项目结构 ai-demo/ ├── .env ├── requirements.txt ├── chat_demo.py ├── function_calling.py └── rag_service/ ├── main.py ├── embedding_util.py └── search_util.py3.3 版本兼容提醒大模型 API 迭代速度很快。不同版本的 SDK 对参数名称、返回结构可能略有差异。下面代码里出现的模型名称和字段在发布时是常见写法但你实际运行时应以官方文档或控制台信息为准。4. 核心代码实战对话与函数调用4.1 发起一次普通对话先来一个最简单的对话调用。在项目根目录创建chat_demo.pyimport os from openai import OpenAI from dotenv import load_dotenv load_dotenv() client OpenAI( api_keyos.getenv(ZHIPU_API_KEY), base_urlos.getenv(ZHIPU_BASE_URL, https://open.bigmodel.cn/api/paas/v4/) ) def chat(text: str, model: str glm-4-plus) - str: response client.chat.completions.create( modelmodel, messages[ {role: user, content: text} ], temperature0.3, ) return response.choices[0].message.content if __name__ __main__: print(chat(你好请用一句话介绍大模型应用开发的难点。)).env文件内容ZHIPU_API_KEY你的API密钥 ZHIPU_BASE_URLhttps://open.bigmodel.cn/api/paas/v4/运行命令python chat_demo.py预期输出是一段简短的文字回答。这里的关键参数说明如下temperature0.3控制随机性数值越低回答越稳定适合业务场景。base_url指向兼容接口的根地址。model具体可用模型ID以控制台为准。4.2 流式输出体验对话类应用的体验优化通常离不开流式输出。把上面的chat函数改成生成器形式def chat_stream(text: str, model: str glm-4-plus): stream client.chat.completions.create( modelmodel, messages[ {role: user, content: text} ], streamTrue, ) for chunk in stream: delta chunk.choices[0].delta.content if delta: yield delta调用方式if __name__ __main__: for piece in chat_stream(写一段关于大模型成本优化的建议。): print(piece, end, flushTrue)流式输出要注意一点如果接口返回的delta.content为None代表当前分片可能只有角色信息或工具调用字段需要过滤掉否则会打印出None。4.3 Function Calling 完整流程Function Calling 是很多业务场景的基石。我们以一个“查询天气”的工具为例。第一步定义工具描述。第二步让模型判断是否需要调用工具。第三步程序执行真实函数。第四步把结果回传给模型生成最终回答。创建function_calling.pyimport os import json import requests from openai import OpenAI from dotenv import load_dotenv load_dotenv() client OpenAI( api_keyos.getenv(ZHIPU_API_KEY), base_urlos.getenv(ZHIPU_BASE_URL, https://open.bigmodel.cn/api/paas/v4/) ) TOOLS [ { type: function, function: { name: get_weather, description: 查询指定城市的实时天气返回温度和天气状况, parameters: { type: object, properties: { city: {type: string, description: 城市名称} }, required: [city] } } } ] def get_weather(city: str) - str: # 这里只是一个示例函数真实业务中请替换为天气服务 API return json.dumps({city: city, weather: 晴, temperature: 24}, ensure_asciiFalse) def run_with_tool(user_input: str): messages [{role: user, content: user_input}] resp client.chat.completions.create( modelglm-4-plus, messagesmessages, toolsTOOLS, ) msg resp.choices[0].message if not msg.tool_calls: print(最终回复, msg.content) return tool_call msg.tool_calls[0] args json.loads(tool_call.function.arguments) print(模型请求调用工具, tool_call.function.name, args) result get_weather(args[city]) messages.append(msg) messages.append({ role: tool, tool_call_id: tool_call.id, content: result }) final client.chat.completions.create( modelglm-4-plus, messagesmessages, toolsTOOLS, ) print(最终回复, final.choices[0].message.content) if __name__ __main__: run_with_tool(北京现在天气怎么样)这段代码的核心逻辑tools参数向模型声明可用函数。模型如果决定调用工具会在tool_calls里返回函数名和参数。程序用tool_call.id把真实结果关联回对话。回传后模型基于工具结果生成友好回答。注意不同版本 SDK 对tool_call.id的字段名可能略有差异如果出现AttributeError检查 SDK 版本或打印msg结构来确认字段名。5. RAG 知识库问答落地案例5.1 需求与设计如果说 Function Calling 解决的是“模型与系统交互”RAG 解决的是“模型如何访问私域知识”。RAGRetrieval-Augmented Generation检索增强生成核心思想是不要把知识塞进模型参数而是先从一个外部知识库检索相关内容再把检索结果拼进 Prompt让模型基于真实材料回答。一个知识库问答系统需要四个模块文本切分。向量化。向量存储与相似度检索。问答服务接口。5.2 数据切片、向量化与检索这里引入向量数据库做本地示例。实际生产环境可以换成 Elasticsearch、Milvus、pgvector 等。先看文本切分和向量化# rag_service/embedding_util.py from openai import OpenAI import os from dotenv import load_dotenv load_dotenv() client OpenAI( api_keyos.getenv(ZHIPU_API_KEY), base_urlos.getenv(ZHIPU_BASE_URL, https://open.bigmodel.cn/api/paas/v4/) ) def get_embedding(text: str): resp client.embeddings.create( modelembedding-3, inputtext ) return resp.data[0].embedding再写一个简单切分函数def split_text(text: str, chunk_size: int 500, overlap: int 50): chunks [] start 0 while start len(text): end start chunk_size chunks.append(text[start:end]) start end - overlap return chunks切分参数不是固定的。一般建议中文场景按 300~800 字切分。保留少量 overlap防止关键信息被切断。如果文本本身有段落结构优先按段落切分再按长度兜底。向量存储检索# rag_service/search_util.py import chromadb from embedding_util import get_embedding client chromadb.Client() collection client.get_or_create_collection(kb_docs) def add_docs(docs: list, ids: list): embeddings [get_embedding(d) for d in docs] collection.add( idsids, documentsdocs, embeddingsembeddings ) def search(query: str, top_k: int 5): q_emb get_embedding(query) results collection.query( query_embeddings[q_emb], n_resultstop_k ) return results[documents][0]注意不同版本 Chroma 的 API 会有差异比如create_collection与get_or_create_collection的行为不同。运行前先确认版本。5.3 问答服务 FastAPI 集成把检索结果拼进 Prompt并对外提供 HTTP 接口# rag_service/main.py from fastapi import FastAPI from pydantic import BaseModel from search_util import search from openai import OpenAI import os from dotenv import load_dotenv load_dotenv() app FastAPI() client OpenAI( api_keyos.getenv(ZHIPU_API_KEY), base_urlos.getenv(ZHIPU_BASE_URL, https://open.bigmodel.cn/api/paas/v4/) ) class QARequest(BaseModel): question: str def build_prompt(question: str, context_docs: list) - str: context \n---\n.join(context_docs) return f 请基于以下资料回答用户问题。如果资料中没有答案请直接回答“资料中未找到相关信息”不要编造。 资料内容 {context} 用户问题 {question} app.post(/api/qa) def qa(req: QARequest): docs search(req.question) prompt build_prompt(req.question, docs) resp client.chat.completions.create( modelglm-4-plus, messages[ {role: system, content: 你是企业知识库助手。}, {role: user, content: prompt} ], temperature0.2, ) return {answer: resp.choices[0].message.content, sources: docs}5.4 运行与验证启动服务uvicorn rag_service.main:app --reload --host 0.0.0.0 --port 8000另开一个终端测试curl -X POST http://127.0.0.1:8000/api/qa \ -H Content-Type: application/json \ -d {question: 报销流程是什么}预期结果{ answer: ..., sources: [检索到的原始文档片段] }这里要特别注意如果检索结果本来就不好模型回答必然不会好。RAG 系统的瓶颈通常在“检索质量”而不是“生成质量”。你可以先人工打印sources看看是否相关再谈 Prompt 优化。6. 大模型应用“走弯路”清单常见问题与排查把前面几节实战中容易踩坑的问题汇总成一张排查表方便直接对照。问题现象常见原因解决思路返回内容报None相关错误分片中没有content字段可能是流式分片仅有角色信息过滤空值检查delta字段模型总是拒绝回答Prompt 约束过强或系统提示词冲突简化指令明确边界避免重复约束Function Calling 没被触发工具描述不够明确或用户输入不需要工具检查description是否包含触发关键词工具调用死循环Agent 不断重复同一个工具调用设置最大轮次增加结果去重逻辑回答出现幻觉缺少 RAG 或知识时效性不足接入检索增强并要求模型标注来源请求超时大模型推理耗时长未设置超时增加超时时间配合流式输出提升体验成本飙升Prompt 体积过大、调用次数过多做缓存、压缩文档、用小模型分流排查工具方面建议从三件事开始打开接口日志记录每一次调用的输入、输出、耗时、token 数。保留带有真实业务数据的回放集方便复现问题。把 Prompt 和代码分开管理Prompt 变动要可追溯。7. 评测、监控与成本治理7.1 建立业务评测集很多团队对大模型应用的效果判断停留在“人肉点测”。这不够。 上线前至少准备一份业务评测集覆盖核心场景。每个场景包含正常输入、边界输入、非法输入。每条用例标注期望行为关键词比如“必须包含订单号”“必须拒绝无关问题”。评测方式可以选择人工打分、规则校验、强模型评估三种结合。强模型评估是指用能力更强的模型给业务回答打分它适合快速回归但不建议完全替代人工。7.2 关键监控指标上线后关注四个维度可用性调用成功率、错误码分布。性能首字延迟、总响应时间、排队量。质量用户点赞点踩率、无效回答比例、转人工率。成本每日 token 量、单次请求成本、缓存命中率。7.3 成本优化策略实测项目中最有效的手段缓存重复问题直接返回历史答案。分流简单问题用轻量模型复杂问题用强模型。压缩清理历史消息只保留必要上下文。批处理离线任务合并请求避开高峰期。蒸馏高频固定任务可以训练一个小模型替代。8. 工程最佳实践8.1 配置与密钥管理API Key 只放在环境变量或密钥管理服务中。代码仓库的.env.example只放占位符。服务端尽量减少密钥的暴露范围按调用方分配独立凭证。8.2 异常处理与限流大模型接口不像普通 HTTP 接口那样稳定可控建议在代码中统一处理import time import requests def call_with_retry(func, max_retries3): for attempt in range(max_retries): try: return func() except Exception as e: if attempt max_retries - 1: raise time.sleep(2 ** attempt)同时要处理服务端限流。不要在拿到 429 后疯狂重试应该退避等待或把请求分散到不同时间片。8.3 安全与合规面向企业场景的大模型应用必须考虑数据边界私域数据默认不进入外部共享训练流程。涉及个人信息时要做脱敏。工具调用涉及写操作时需要人工确认或权限校验。输出内容要做敏感词过滤和合规检查。生产环境中任何删除、更新类操作都要有审计日志。8.4 灰度发布与回滚Prompt 调整和模型版本切换都是高风险的变更。建议使用可配置的 Prompt 模板而不是硬编码。把模型版本作为发布参数支持一键切回。先对 5%~10% 流量试运行再逐步放大。8.5 提示词与流程管理Prompt 也是代码。团队内部应该建立 Prompt 版本管理流程包括版本号、变更人、变更理由和评测结果。避免出现“上一版效果更好但不知是谁改的”这种情况。9. 总结与后续学习路线回到开头的问题。智谱AI 的唐杰教授坦言“走了弯路”这句话对行业最大的价值不是提醒我们去讨论某一家公司的市值变化而是提醒每个做 AI 应用的人技术能力强不等于产品成功模型跑通不等于业务闭环。通过这篇文章你可以掌握以下内容大模型技术路线的三个核心决策点。智谱AI 开放平台 API 的基本接入方式。Function Calling 从工具定义到结果回传的完整流程。RAG 知识库问答的最小可运行方案。大模型应用常见的坑点与排查方法。评测、监控、成本治理和工程最佳实践。下一步你可以按这个顺序继续深入用本文代码搭建一个最小对话应用。接入你自己的业务数据库或文档库构建 RAG 服务。设计一份 50 条用例以上的评测集记录基线效果。研究 Agent 多工具协作的编排框架比如 ReAct 模式的实现。实际项目中优先关注的仍然是数据安全、成本失控和效果回归这三个风险。先把它们设计到系统里再谈更多花哨的智能化能力。如果这篇文章对你有帮助收藏备用后续会补更多大模型工程化实战的排错与架构笔记。
返回列表