尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

大模型工程化实战:从Agent开发到私有化部署的完整路径

大模型工程化实战:从Agent开发到私有化部署的完整路径 北大校友的AI战事听起来像是一个商业故事但放到技术语境里它真正指向的是一个问题AI产品的比拼已经从模型参数、论文数量转移到了工程落地能力。一个模型在演示环境里效果惊艳一旦接入真实业务可能立刻暴露出Prompt不稳定、返回格式不对、上下文被截断、工具调用失败、并发一高就超时以及成本失控等一系列问题。这篇内容围绕AI应用开发与部署这条主线展开从技术选型、最小Agent实现、模型幻觉治理、私有化部署到常见问题排查梳理AI从“能跑”到“能用”所需要的工程思路。适合正在做AI应用开发或者准备把大模型接入业务系统的后端工程师、算法工程师和架构师。1. AI战事的主战场已经转移到工程落地1.1 为什么AI项目容易卡在“能跑”和“能用”之间很多团队第一次把大模型接进业务时都会经历同一个过程本地写好一个Prompt跑通一次对话然后信心满满地部署测试环境。结果到了联调阶段模型偶尔会答非所问偶尔返回一段Json里夹着解释文字偶尔因为输入太长直接报错。这些问题不是模型“不够聪明”而是工程链路没有闭环。Demo阶段只需要验证“模型能不能回答出正确答案”生产阶段却要回答“模型在大量请求下是否稳定、是否安全、是否可观测、是否可控”。两者之间至少隔着四道关输入关用户输入无法预判格式、长度、语气、敏感词都可能变化。输出关模型输出不是结构化数据如何保证下游系统能解析。质量关模型会产生幻觉如何通过评测集、约束和兜底减少错误。运维关API延迟、并发、成本、日志、监控和安全权限都要纳入设计。如果只把模型当作一个黑盒HTTP服务用临时脚本去调用项目大概率会在联调后停滞。真正的AI工程化是把模型嵌入现有系统的具体链路中让“模型能力”变成“业务能力”。1.2 从模型SDK到Agent框架技术栈如何选型AI应用不是只有模型调用它会涉及模型服务、开发框架、数据存储、可观测性等多个层次。以当前常见的AI应用技术栈为例可以分成五层层次常见选型主要作用模型层OpenAI、国产大模型API、开源模型本地部署提供推理能力接入层OpenAI SDK、Hugging Face、vLLM、Ollama统一请求和响应编排层LangChain、LlamaIndex、Spring AI、自研Agent实现多轮、工具调用、检索增强数据层PostgreSQL、Redis、向量数据库保存知识、会话、缓存和向量可观测层日志、指标、链路追踪、评测集验证效果和定位问题技术栈选型的关键不是追新而是看团队已有的语言生态。Python团队通常会选LangChain或LlamaIndex因为生态丰富适合算法原型和Agent实验Java团队可以考虑Spring AI它把大模型封装成类似Spring Data的风格方便在已有Spring Boot项目中集成。这里要注意框架只是减少重复劳动真正决定效果的是Provider、Embedding模型、向量库和业务逻辑怎么配合。一个容易踩的坑是“为了用框架而用框架”。如果业务只是单纯文本问答直接调SDK加一个Prompt模板就够了完全没必要引一套Agent框架。框架带来的抽象和版本复杂性在简单场景里反而是负担。先明确需求再选择框架这个顺序不能反。2. 环境准备开发机、依赖和模型服务三件事要提前对齐2.1 本地开发环境怎么配在开始写Agent之前先把开发环境对齐。下面以Python和Java两个生态为例展示最基础的依赖安装方式。Python侧建议使用3.10及以上版本当前主流Agent框架和大模型SDK对3.10/3.11/3.12支持较好。python3 --version pip install openai langchain langchain-openai如果使用Java生态通过Maven引入Spring AI。这里要注意Spring AI的版本迭代很快不同版本对应的模型接口和自动配置类有差异。落地前必须去官网或Maven仓库确认当前稳定版本不要直接复制旧项目的依赖坐标。dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId version待确认/version /dependency安装完成后检查是否成功python -c import openai; print(openai.__version__)常见的本地环境问题集中在Python版本过低、虚拟环境未激活、多个Python命令指向不同解释器这三点。建议每个项目单独创建虚拟环境避免包依赖互相污染。2.2 模型服务选API还是本地部署模型服务是AI应用的运行基础。这里有两种常见形态直接调用大模型API或者在自有服务器上部署开源模型。两种形态适合不同阶段和业务场景。维度调用API本地部署开源模型使用成本按Token计费初期成本低需要GPU服务器硬件成本高数据安全数据会发送到模型服务商数据完全留存在内部网络延迟依赖网络和厂商服务局域网内延迟可控运维难度低厂商负责稳定性高需要处理显存、并发、驱动模型可控性受厂商更新影响可以固定版本可微调适用场景原型验证、松耦合业务对数据安全要求高的企业场景学习阶段建议先用API跑通逻辑尽快验证业务可行性。当业务稳定跑起来后如果依赖合规、数据安全或成本控制再考虑切换到私有化部署。2.3 使用云主机部署时的基础配置当项目进入私有化部署阶段需要一台带GPU的云服务器。操作系统建议使用Ubuntu 22.04 LTS因为NVIDIA驱动、CUDA和主流推理框架的兼容性资料比较齐全。基础环境检查命令如下nvidia-smi # 查看GPU和驱动 nvcc --version # 查看CUDA版本 docker version # 查看Docker是否可用如果还没装Docker可以使用官方脚本安装但生产环境不建议直接使用脚本安装应该使用镜像仓库或内部软件源并锁定版本。部署推理服务时建议使用Docker隔离环境避免把模型运行依赖直接装进宿主机。docker pull vllm/vllm-openai:latest这里有两个容易忽略的点一是宿主机内核和驱动版本要兼容二是容器内CUDA版本要与GPU驱动匹配。不要只关注模型推理框架的版本而忽略底层驱动环境。如果前后版本不一致启动时可能出现“CUDA driver version is insufficient”之类错误。3. 用最短路径实现一个AI Agent应用3.1 先拆需求Agent要解决什么任务AI Agent不是简单的“聊天机器人”它需要把大模型和外部工具结合起来完成一个用户目标。这里以一个简化版客服Agent为例任务设定如下。用户可以通过自然语言查询订单状态Agent需要判断用户意图必要时调用订单查询接口再基于查询结果生成回答。这个例子覆盖了Agent的三大核心环节意图识别、工具调用、结果组装。在没有Agent框架的情况下直接使用大模型的Function Calling能力也可以实现。输入示例用户帮我查一下订单20241215001现在到哪了预期处理过程将用户问题发给大模型附带订单查询工具定义。模型返回需要调用工具的参数比如订单号。程序调用本地订单查询函数拿到真实订单数据。将订单数据回传给模型生成面向用户的回答。3.2 基于OpenAI SDK实现带工具调用的Agent下面给出一段可以运行的Python代码。这段代码不依赖LangChain只使用OpenAI SDK便于理解Agent最核心的执行循环。from openai import OpenAI import json client OpenAI( api_keyyour-api-key, base_urlyour-model-endpoint # 使用兼容OpenAI协议的API时可以配置 ) # 模拟订单查询 def query_order(order_id: str) - dict: order_table { 20241215001: {status: 已发货, location: 杭州转运中心}, 20241215002: {status: 待支付, location: }, } return order_table.get(order_id, {status: 未找到, location: }) # 定义工具供模型识别 tools [ { type: function, function: { name: query_order, description: 根据订单号查询订单状态和当前位置, parameters: { type: object, properties: { order_id: { type: string, description: 用户提供的订单号 } }, required: [order_id] } } } ] def run_agent(user_input: str): messages [{role: user, content: user_input}] response client.chat.completions.create( modelgpt-4o-mini, messagesmessages, toolstools, tool_choiceauto ) message response.choices[0].message messages.append(message) if message.tool_calls: for tool_call in message.tool_calls: args json.loads(tool_call.function.arguments) result query_order(args[order_id]) messages.append({ role: tool, tool_call_id: tool_call.id, content: json.dumps(result) }) second_response client.chat.completions.create( modelgpt-4o-mini, messagesmessages ) return second_response.choices[0].message.content return message.content if __name__ __main__: print(run_agent(帮我查一下订单20241215001现在到哪了))这里的执行逻辑值得拆开解释。第一步把用户问题和工具定义一起发给模型让模型决定是否调用工具。第二步模型如果返回tool_calls说明它希望执行某个函数程序拿到参数后调用真实业务函数并把结果作为tool消息回填给模型。第三步模型根据真实结果生成最终回答。这段代码有两个容易出错的地方。第一不同版本模型的工具调用参数名称可能不一致需要确认使用的是tools还是functions。第二tool_call_id必须原样回传否则多轮对话会报错。实际项目中还要增加最大轮数限制防止模型反复调用工具造成死循环。3.3 通过Spring AI在Java项目中使用大模型如果团队技术栈是Java可以使用Spring AI降低接入成本。Spring AI将常见的ChatClient、EmbeddingClient封装成Bean可以直接注入到Service中使用。下面是一个极简示例。Service public class OrderAssistantService { private final ChatClient chatClient; public OrderAssistantService(ChatClient.Builder builder) { this.chatClient builder.build(); } public String ask(String userMessage) { return chatClient.prompt() .user(userMessage) .call() .content(); } }如果你的Spring Boot版本是3.x且使用Maven那么引入Spring AI starter之前要确认项目Java版本是否满足要求。当前Spring AI对Spring Boot 3.2以上版本支持较好原始材料没有给出明确版本时建议建立一个简单的示例工程先跑通再集成到业务代码中。Java侧实现Agent会比Python更繁琐因为它需要更多类型定义和工具注册。对于简单场景直接使用ChatClient即可对于复杂流程可以使用Spring AI提供的Tool注解把方法注册为模型可调用的工具。实际项目里我会先判断团队维护成本。如果团队后端全是Java引入Python独立服务会增加链路复杂度用Spring AI更统一如果团队已经有一部分Python算法服务也可以把Agent编排放在Python侧Java只对外提供HTTP接口。4. 模型幻觉与输出质量上线前必须解决的问题4.1 先理解模型幻觉的成因模型幻觉是指模型生成的内容看起来合理但与事实不符。它的根源在于大模型的本质是根据上下文预测下一个Token而不是从数据库里查询事实。模型内部没有“事实表”所有知识都承载在参数里因此当它不确定时仍然会生成大概率合理的文本而不是诚实地说“不知道”。在AI应用里幻觉会造成很严重的后果。比如客服Agent可能编造一个不存在的订单状态知识库问答可能错误回答公司政策代码生成工具可能给出并没有经过验证的API。规避幻觉的第一步不是增加提示词里的“你必须准确”而是在架构上给模型提供更可靠的信息来源。4.2 降低幻觉的工程手段提示词、RAG、工具约束当前工程实践中降低幻觉主要有三条路线。第一优化Prompt。让模型只基于给定材料回答如果没有找到答案就明确说不知道。这种做法的成本最低但不能完全杜绝幻觉。你是一位订单客服助手。请只根据下面的订单信息回答问题。 如果订单信息中不包含用户所需内容请回答“我暂时没有查到该订单信息”。 不要推测不要编造。 订单信息 {order_result}第二引入检索增强生成RAG。把需要回答的业务资料先切分成切片存入向量数据库用户提问时先检索相关片段再把这些片段拼接进Prompt让模型基于片段回答。RAG的核心是“先找证据再回答”能明显缓解模型对私有知识一无所知的问题。第三工具约束。通过Function Calling或结构化输出让模型只负责“提取参数”或“选择动作”而不是直接生成事实性内容。比如要查询订单就让模型调用订单接口拿到结果后再生成回答不要让它凭记忆猜订单状态。以上三种方法可以组合使用。文本生成任务优先用Prompt约束和RAG动态数据查询任务优先用工具约束。4.3 建立评测集和人工兜底模型效果无法通过“看几个例子”来确认必须建立小规模评测集。最简单的方式是准备一组输入、预期行为或关键指标然后批量运行Agent观察输出是否满足要求。例如订单客服Agent可以准备20条真实历史问题用以下规则做自动检查。评测点检查方式是否能正确提取订单号正则检查输出或工具调用参数是否包含虚构订单状态人工抽取样例定期复查是否包含“我不确定”类兜底话术字符串匹配关键词工具调用是否在最大轮数内结束统计解析Agent执行日志返回格式是否符合下游解析JSON Schema或类型校验在代码里可以用一个简单的Python脚本批量调用Agent并把输出保存到文件里便于人工检查。python evaluate_agent.py --input test_cases.json --output result.jsonl生产环境还需要人工兜底。当模型置信度低或者输出没通过校验规则时不要直接返回给用户而是把风险较高的会话转入人工处理队列。这里要注意不能依赖“置信度低”这种模型输出概率最简单可控的方式是设计一套规则校验比如关键实体是否为空、是否包含“未找到”“可能”“大概”之类模糊词命中规则就走人工。5. 模型部署从开发到生产还有一段路5.1 私有化部署选型当业务需要把模型放在自有环境时可选的开源推理方案很多。Ollama适合单机快速试验vLLM适合高并发生产环境Hugging Face TGI则是企业级服务选择。下面用一个表格归纳差异。方案显存要求并发能力易用性适合场景Ollama低到中一般高一条命令拉起服务本地调试、DemovLLM高高支持Continuous Batching中需要配置生产环境高并发Hugging Face TGI高高中与HF生态集成紧密的企业以Ollama为例一条命令即可拉起一个兼容OpenAI协议的服务ollama pull llama3.1:8b ollama serve如果使用vLLM常见的启动命令是vllm serve Qwen/Qwen2.5-7B-Instruct \ --host 0.0.0.0 \ --port 8000 \ --gpu-memory-utilization 0.8启动后应用层通过一个与OpenAI兼容的endpoint访问本地模型。这里需要注意OpenAI SDK的base_url要改成本地服务地址否则会请求到外部服务。5.2 部署后的稳定性验证模型服务启动成功不代表可以上线。上线前至少要做三件事。第一单请求验证。检查返回格式是否与代码里预期一致尤其要确认模型名称、响应字段、流式输出是否兼容。curl http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: Qwen/Qwen2.5-7B-Instruct, messages: [{role: user, content: 你好}], max_tokens: 128 }第二并发压测。使用wrk或Locust发送模拟请求观察模型服务在预期并发下是否出现超时、显存溢出和请求排队。压测要在与生产接近的数据量和上下文章长度下进行不要用几个字的短问题代表真实负载。第三重试和降级。应用层要设置超时时间、重试次数和熔断逻辑。由于大模型推理耗时通常高于普通HTTP接口应用层不能沿用普通接口的超时配置。一个常用起点是30秒到60秒超时并根据模型响应时间动态调整。5.3 生产环境还需要额外关注什么私有化部署远不止启动一个模型服务这么简单。生产环境至少要补齐这些能力日志记录每次请求的模型、Token数、延迟、返回状态。监控GPU显存、GPU利用率、请求排队数、服务重启次数。权限模型服务端口要放在内网通过网关控制访问不要直接暴露公网。版本管理模型文件、推理框架、代码版本三者要一起记录方便回滚。成本控制统计每个业务线消耗的Token数和GPU使用率及时发现异常增长。异常处理模型服务挂掉时应用层要有降级文案或备份模型。这几个能力不是上线后补而是在设计阶段就要纳入。否则一旦线上出现故障你连“是模型问题还是网络问题”都无法判断。6. 常见问题排查从现象到根因的排查路径6.1 模型返回异常、格式不稳定或空响应这是AI应用最常遇到的问题。现象包括模型返回了多余的解释文字、JSON解析失败、返回空字符串、或者回答与业务无关。排查顺序建议如下。先保存原始响应体确认是模型输出本身异常还是代码解析异常。检查Prompt是否明确要求只输出JSON并给了示例格式。检查模型参数temperature值越大输出越随机结构化任务建议设成0或接近0。检查上下文长度如果输入过长导致截断模型可能无法生成完整内容。检查是否流式返回时解析方式错误部分模型平台流式数据格式不同。一个稳妥的做法是增加“格式修正”环节如果JSON解析失败把错误信息回传给模型让它重新生成。但这会增加一次请求因此更适合低频场景。生产环境可以在前置阶段牺牲一点灵活性用Function Calling或JSON Mode强制输出结构。6.2 并发上去后接口超时或OOM大模型推理是CPU和GPU密集操作并发能力远低于普通Web接口。很多团队把用户请求直接同步调用模型服务结果压测时一上来就超时。常见原因有三个现象常见原因检查方式处理建议请求排队严重GPU显存不足推理批处理能力低查看GPU利用率、排队数使用vLLM的Continuous Batching增加并发参数应用线程阻塞HTTP客户端连接池太小查看应用线程数和队列增大连接池使用异步调用进程OOM上下文过长导致显存暴涨检查max_model_len、显存监控限制上下文长度降低batch size实际项目里应用层要控制并发不要把所有请求瞬间打到模型服务上。可以加一个队列或限流器让系统在压力超过上限时快速失败而不是无限排队。这样可以保护模型服务也更容易定位瓶颈。6.3 依赖冲突和版本不匹配LangChain、Spring AI这类框架迭代很快经常出现两个问题一是项目里多个模块引入了不同版本的SDK二是框架版本与模型API返回结构不兼容。从现象上看可能是启动报ClassNotFoundException或者是调用时出现“unexpected response format”。排查步骤使用pip list或mvn dependency:tree查看依赖版本。确认模型API接口文档要求的版本范围。将Agent逻辑从框架中摘出来用最简SDK写一个调用验证模型侧是否正常。如果是新接入的模型先看是否兼容OpenAI协议很多开源模型服务都支持但字段有细微差异。预防方式很直接给项目锁定依赖版本使用依赖锁文件或Maven多模块统一版本管理。不要每周都升级框架除非有明确的新特性或安全修复。7. AI工程化最佳实践与下一步方向7.1 可复用的上线检查清单在把AI应用发布到生产之前建议按下面的清单逐项确认。模型账号、API Key是否通过环境变量或密钥管理注入不写在代码里。模型名称、版本、Endpoint是否在配置中心统一维护。Prompt是否沉淀为版本化配置修改时能追溯。是否准备好评测集至少覆盖正常、边界和异常三类输入。是否设置请求超时、重试和最大轮数限制。是否处理了模型返回空结果、格式错误和资源不可用等异常分支。是否在关键操作加入人工确认例如下单、支付、数据删除等高风险动作。是否在日志中记录请求ID、Token用量、延迟和模型版本。是否对模型服务配置了监控和告警。是否明确了回滚方案例如切回旧Prompt、旧模型或关闭Agent功能。清单里的每一项都是生产事故中总结出来的。对照检查时不要只看“有没有”还要看“是不是真的生效”。7.2 从单个Agent到完整AI系统的扩展方向当最小Agent已经能稳定运行后面的扩展方向通常有五个。一是Agent编排。从单工具调用扩展到多步骤、多角色协作比如客服Agent在查订单后自动生成工单再调用通知服务。二是RAG知识库。给模型接上企业文档、帮助中心、历史工单实现更可控的垂直领域问答。要把重点放在切片策略、检索召回率和引用溯源上。三是多模型路由。根据任务难度和成本在免费模型、通用模型、专业模型之间做路由降低整体推理成本。四是模型微调。当Prompt和RAG都无法满足效果时用少量业务数据微调模型。微调是一项昂贵且需要评测支撑的工作不要在产品早期就投入。五是AI编程辅助。在开发环境中使用Cursor、JetBrains AI插件之类的AI Coding工具辅助生成模板代码、补全测试用例和解释历史代码。AI Coding工具能提升效率但代码审查和自动化测试仍然不能省略AI生成的代码同样可能包含错误。无论从哪个方向扩展核心仍然不变AI战事拼的是谁能把模型能力用工程手段变成稳定、安全、可维护的业务能力。这一步走扎实了后面的模型升级、业务增长和新场景接入才会有稳定地基。
返回列表