公司动态

从Move 37到AI工程化:模型部署与Agent开发实战指南

📅 2026/8/30 14:17:25
从Move 37到AI工程化:模型部署与Agent开发实战指南
最近 AI 圈子里始终绕不开一个词Move 37。它来自 2016 年 AlphaGo 与李世石的围棋对战。在那场举世瞩目的第二局中AlphaGo 下出了第 37 手——一步违反人类围棋直觉、被解说员认为是“失误”的棋。但整盘棋结束后所有复盘的人都意识到这手棋恰恰是胜负手。它代表一种非人类的计算视角也是 AI 开始突破人类经验边界的一次标志性事件。放在 2026 年重新看 Move 37更像是一种隐喻今天我们在 AI 应用开发、模型部署、Agent 工程化里遇到的很多反直觉现象本质上和“第 37 手”是同一件事——AI 不再只是按人类的经验做重复劳动而是开始用高维计算逻辑改变工程流程本身。本文想围绕这个隐喻系统性拆解当前 AI 工程实践中最值得关注的四件事从实验到部署模型服务化究竟怎么做Agent 开发的关键组件与编排方式一个可落地的会议纪要助手完整实战高频报错、工程红线与最佳实践。无论你是刚接触大模型开发的新手还是已经负责 AI 应用落地的后端工程师这篇文章都会给你一条能照着执行的完整路径。1. Move 37 的隐喻为什么 AI 工程化逐渐“无处不在”1.1 什么是 Move 37先还原一下那手棋。2016 年 3 月AlphaGo 与李世石进行人机大战。第二局第 37 手AlphaGo 在棋盘中央落子这手棋完全不在人类棋手的常规判断体系里。当时直播间的解说员认为 AlphaGo 犯错了但后续的胜率模型分析显示这手棋让胜率大幅上升。这手棋的意义不在于“AI 赢了谁”而在于它展示了 AI 的核心价值不必依赖人类已有的经验路径而是通过大量模拟和策略搜索找到更优解。1.2 从围棋到软件工程AI 的应用演进把视角从围棋搬到软件开发会发现类似的“Move 37 时刻”正在各个方向出现AI 编程原本被认为必须由人类逻辑推导完成的代码生成、代码重构、单元测试补充现在可以由大模型自动生成并且不断被集成进 IDE 工作流。AI Agent早期的机器人流程自动化只能按固定规则执行现在的 Agent 可以根据目标自主拆分行动、调用工具、读取结果、调整计划。模型部署以前部署一个深度学习模型需要大量算法工程师和运维协作现在通过标准化的推理服务、镜像和 PAI 平台普通后端开发也能完成。多模态应用文本、图片、音频、视频统一建模后AI 应用从单一 NLP 场景扩展到内容生成、客服、审核、营销、教育等领域。这些变化的共同点是AI 正在从“实验室里跑通的模型”走向“生产环境的稳定服务”。这个过程也伴随着大量工程问题模型幻觉、上下文丢失、接口超时、Token 成本、数据安全、灰度方式。所以“Move 37 is suddenly happening everywhere”这句话放到开发者语境下可以理解成AI 已经落地为一种常规工程组件我们需要用工程化的方式接住它。1.3 为什么开发者需要关注 AI 工程化很多开发者担心 AI 会取代编程岗位。实际上从当前工程实践来看AI 更像是在改变开发的方法论。需求理解层面AI 可以生成初版代码但无法代替业务方确认需求边界。代码实现层面AI 建议、代码补全能显著提效但代码审查、风险控制、性能分析仍需人工介入。部署运维层面模型版本、Prompt 版本、特征版本都是需要管理的资产。换句话说未来的核心竞争力是“会用 AI 的工程师”而不是“所有代码靠手敲的工程师”。理解 AI 如何建模、部署、编排比单纯背 API 更有长期价值。2. AI 工程化的技术栈与环境准备2.1 当前 AI 应用开发的主流形态在开始部署和编码之前先给出 2026 年开发者用得最多的几种技术形态形态说明典型场景LLM API 调用直接调用大模型服务通过 HTTP 请求完成文本生成、代码生成快速搭建 AI 功能私有化模型部署将开源模型部署到自有服务器或云服务器数据隔离、离线可用Prompt Engineering通过提示词工程控制模型输出Agent、客服、翻译RAG检索增强生成将私有知识库检索结果与 LLM 生成结合企业知识库问答Agent 编排让模型自主规划并调用工具完成复杂任务自动化运营、数据分析模型微调在基础模型之上用业务数据继续训练垂直行业效果优化标题“AI changes everything”虽然听起来很大但落到工程上本质还是上述技术组合。我们不需要一口气掌握全部只需要先打通“调用 → 部署 → 编排”这条链路。2.2 推荐技术栈围绕 AI 工程实践我建议的学习技术栈如下语言Python生态最丰富适合实验与数据分析、Java很多后端团队的主语言可借助 Spring AI 快速集成模型访问OpenAI 兼容 API、国内大模型平台 API、vLLM / Ollama 私有化推理服务框架FastAPIPython 服务、Spring BootJava 服务Agent 框架LangChain、LlamaIndex、Spring AI、自研工具调用循环向量数据库Milvus、Chroma、pgvector、Elasticsearch容器化Docker、Kubernetes可观测性Prometheus Grafana、LangSmith、自定义日志链路注意不同版本之间接口差异可能很大。特别是 LangChain、Spring AI 这类迭代很活跃的框架API 经常变化。后面代码示例会说明“当前主流写法的思路”你使用时必须以自己的依赖版本为准。2.3 本地环境准备下面是一份适合大多数项目的环境清单Python 3.10 以上建议使用 3.11 或 3.12Node.js 18 部分工具链需要Docker Desktop本机容器化推理GitIDEVS Code Python 插件或 PyCharm一个可用的 LLM API Key如 OpenAI 或国内兼容平台或者本地部署一个 OpenAI 兼容服务本地推理默认可以使用 Ollama它安装后是一条命令启动模型。例如ollama pull qwen2.5:7b ollama run qwen2.5:7b只要本地跑起了 Ollama就相当于拥有了一个 OpenAI 兼容的服务地址http://localhost:11434/v1后续所有基于 OpenAI SDK 的代码都可以指向它方便本地调试。3. 模型服务化从“能跑”到“稳定可用”3.1 部署一个模型服务最小路径是什么实际生产中我们很少直接调用一个 Python 脚本里的model.generate()。更常见的部署路径是训练或获取一个基础模型。将模型封装成 HTTP 服务。用 Docker 镜像固化环境。部署到服务器或 K8s提供 API。通过网关加上鉴权、限流、监控。从“能跑”到“稳定可用”关键差别就在第 2 到第 5 步。很多项目 Demo 能跑一上生产就崩问题往往出现在 QPS 压测、并发处理、显存占用、超时退出、日志缺失这些工程细节上。3.2 一个最简单的模型推理服务假设你已经有一个本地模型或者通过 API 访问模型用 FastAPI 包一层服务是最常见的方式# 文件路径app/main.py from fastapi import FastAPI, HTTPException from pydantic import BaseModel import openai app FastAPI(titleLLM Proxy Service) client openai.OpenAI( base_urlhttp://localhost:11434/v1, api_keyEMPTY ) class ChatRequest(BaseModel): prompt: str system: str 你是一个有用的助手 temperature: float 0.7 class ChatResponse(BaseModel): answer: str model: str usage: dict app.post(/chat, response_modelChatResponse) async def chat(req: ChatRequest): try: resp client.chat.completions.create( modelqwen2.5:7b, messages[ {role: system, content: req.system}, {role: user, content: req.prompt}, ], temperaturereq.temperature, ) content resp.choices[0].message.content return ChatResponse( answercontent, modelresp.model, usage{ prompt_tokens: resp.usage.prompt_tokens, completion_tokens: resp.usage.completion_tokens, total_tokens: resp.usage.total_tokens, } ) except Exception as e: raise HTTPException(status_code502, detailfmodel service error: {str(e)}) app.get(/health) async def health(): return {status: ok}启动命令uvicorn app.main:app --host 0.0.0.0 --port 8000这样我们就得到一个统一的/chat服务。前端、后端、Agent 都不需要关心真正调用的是本地模型还是云端模型只要遵循统一接口约束即可。3.3 容器化部署为了在服务器上稳定运行需要 DockerfileFROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY app ./app EXPOSE 8000 CMD [uvicorn, app.main:app, --host, 0.0.0.0, --port, 8000]requirements.txt 示例fastapi0.111.0 uvicorn[standard]0.30.1 openai1.35.0 pydantic2.7.0构建并运行docker build -t llm-proxy:latest . docker run -d --name llm-proxy -p 8000:8000 llm-proxy:latest生产环境建议加一层网关负责鉴权、限流、熔断。这不是可有可无而是当模型服务被多个业务方调用时必须有的基础设施。3.4 模型部署的监控指标和普通 Web 服务不同模型服务需要额外关注首 Token 延迟TTFT用户感受到的等待时间核心指标Token 生成速率每秒生成的 Token 数显存占用与 GPU 利用率避免资源浪费或 OOM排队长度在线推理服务并发过高时请求会在队列中堆积错误率与超时率区分 4xx/5xx模型服务故障要能告警。我个人比较推荐先把 FastAPI 服务的访问日志结构化再使用 Prometheus 采集指标。等到规模大了再上 LangSmith 这类 LLM 链路追踪平台。4. Agent 开发从“单次对话”到“工具编排”4.1 什么是大模型 Agent大模型 Agent 可以理解为一个自主使用工具完成任务的程序。简单来说它包含大模型负责理解和生成决策工具例如搜索、代码执行器、计算器、数据库查询器、API 调用器记忆保存用户偏好、历史上下文、阶段性结果规划模块将复杂任务拆成多个子任务。一个典型的 Agent 执行流程如下接收用户目标。大模型判断当前需要调用什么工具。Agent 模块执行工具并拿到结果。将结果回填给大模型。大模型判断任务是否完成若未完成则继续循环。这就是为什么 Agent 比普通问答更接近“AI changes everything”它让模型具备行动能力而不仅仅停留在内容生成。4.2 用代码实现一个极简 Agent 循环先不引入复杂框架用原生 Python 写一个极简 Agent帮助你理解核心逻辑# 文件路径agent/mini_agent.py import json import openai client openai.OpenAI( base_urlhttp://localhost:11434/v1, api_keyEMPTY ) TOOLS [ { type: function, function: { name: get_current_weather, description: 获取指定城市的天气, parameters: { type: object, properties: { city: {type: string, description: 城市名} }, required: [city] } } } ] def get_current_weather(city: str): # 示例工具实际项目中换成天气 API 调用 return f{city} 今日晴25℃ def run_agent(user_query: str): messages [ {role: system, content: 你是一个会调用工具的助手。}, {role: user, content: user_query} ] for step in range(5): resp client.chat.completions.create( modelqwen2.5:7b, messagesmessages, toolsTOOLS, ) msg resp.choices[0].message messages.append(msg) if msg.tool_calls: for tool_call in msg.tool_calls: args json.loads(tool_call.function.arguments) result get_current_weather(**args) messages.append({ role: tool, tool_call_id: tool_call.id, content: result }) else: return msg.content return 已超过最大执行步数 if __name__ __main__: print(run_agent(北京今天天气怎么样))这个示例里的关键点是tools参数和tool_calls返回值。大模型不直接执行业务逻辑它只负责“决定调用哪个工具、传什么参数”真正的执行权仍在你的代码里。这能尽量避免模型幻觉带来的副作用。4.3 什么是 Agent 开发中的“Move 37 时刻”在 Agent 落地过程中我们会遇到不少不符合人类直觉的现象给模型越宽松的指令它可能会做得越差给 Agent 绑定越多的工具它可能会越容易选错工具让模型自己决定“任务是否完成”并不安全有时它会过早终止复杂任务直接丢给大模型不如拆成子任务分工。这些和 AlphaGo 的第 37 手有些类似AI 的计算逻辑和人类的直觉不完全一致。我们需要通过工程机制去约束它而不是靠“更长的 Prompt”。常见手段包括固定 Agent 的最大循环步骤对工具调用结果做 JSON Schema 校验高危操作必须人工确认增加“无工具可用时拒绝作答”规则。5. 完整实战一个可运行的“会议纪要助手”下面通过一个完整的“会议纪要助手”项目把前面讲到的概念串起来。项目目标用户可以上传会议录音的转写文本或粘贴会议记录系统自动生成待办事项、风险项和摘要。5.1 需求分析输入一段会议转写文本。输出会议摘要三个关键待办三个可能风险输出格式采用 Markdown方便直接粘贴到文档工具。能力不依赖额外私有数据使用提示词即可完成。扩展点后续可接入向量数据库把历史会议纪要存起来支持“类似会议”检索。5.2 项目结构meeting-assistant/ ├── app/ │ ├── __init__.py │ ├── main.py │ ├── llm_service.py │ ├── prompt.py │ └── models.py ├── requirements.txt └── README.md5.3 核心代码先定义模型# 文件路径app/models.py from pydantic import BaseModel class MeetingRequest(BaseModel): transcript: str language: str zh class MeetingSummary(BaseModel): summary: str todos: list[str] risks: list[str]提示词建议单独维护# 文件路径app/prompt.py MEETING_PROMPT 你是一个资深的会议纪要整理助手。请根据以下会议转写内容生成结构化会议纪要。 要求 1. 先用不超过100字概括会议核心内容 2. 提取3条待办事项格式为“负责人任务描述截止时间如有” 3. 提取3条潜在风险 4. 所有输出使用中文 5. 不要虚构转写中不存在的细节。 会议转写内容 {transcript} LLM 服务封装# 文件路径app/llm_service.py import openai client openai.OpenAI( base_urlhttp://localhost:11434/v1, api_keyEMPTY ) def generate_meeting_summary(transcript: str) - str: prompt MEETING_PROMPT.format(transcripttranscript) resp client.chat.completions.create( modelqwen2.5:7b, messages[ {role: system, content: 你是一个严谨的会议纪要助手只输出结构化信息。}, {role: user, content: prompt} ], temperature0.2, max_tokens2000, ) return resp.choices[0].message.content注意这里没有把输出直接解析成 Pydantic 对象而是先用字符串生成再交给前端展示。原因是本地模型对 JSON 输出格式的稳定性不太可控业务容错更好。如果使用云端强模型可以改用 JSON Mode。最后是 FastAPI 接口# 文件路径app/main.py from fastapi import FastAPI, HTTPException from app.models import MeetingRequest from app.llm_service import generate_meeting_summary app FastAPI(title会议纪要助手) app.post(/meeting/summary) async def meeting_summary(req: MeetingRequest): if not req.transcript or len(req.transcript.strip()) 20: raise HTTPException(status_code400, detail会议转写内容过短) try: result generate_meeting_summary(req.transcript) return {result: result} except Exception as e: raise HTTPException(status_code502, detailf调用模型失败: {str(e)})5.4 运行与验证启动服务uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload用 curl 测试curl -X POST http://localhost:8000/meeting/summary \ -H Content-Type: application/json \ -d { transcript: 今天讨论了用户登录页面加载慢的问题。前端说首屏图片太大后端说接口响应超过2秒。最后确定下周由前端小王压缩图片后端小李优化缓存测试小张输出性能报告。风险是服务器可能扛不住618流量。 }预期输出是一段包含摘要、待办、风险的 Markdown 文本。如果本地模型能力偏弱可以换更强的云端模型只需修改 base_url 和 model 即可。5.5 扩展方向接入 ASR把录音文件也作为输入用向量数据库保存历史纪要实现相似会议召回增加用户反馈按钮用于后续微调和 Prompt 优化将待办写入项目管理工具 API如 Jira、飞书任务实现闭环。6. 常见问题与排查思路AI 应用开发中报错往往不是单一原因。下面是我在实践中总结的高频问题排查表问题现象常见原因解决思路API 请求超时模型体积大、推理慢或并发高前端调用改为异步服务端增加超时配置使用流式输出改善体验返回内容截断max_tokens 设置过小提高 max_tokens开启 max_tokens 后重试返回 JSON 解析失败模型输出含额外解释文字使用 JSON Mode在 Prompt 中强调“只输出 JSON”用正则兜底提取模型前后回答不一致temperature 过高降低 temperature统一固定 system promptAgent 选错工具工具描述不清晰或工具过多精简工具数量重写工具 name/description增加工具白名单私有化部署显存不足模型参数量大于显卡显存换小参数模型使用量化版本GGUF、GPTQ开启 CPU Offload日志里出现乱码编码不一致统一 UTF-8检查终端字体日志框架设置 charset服务启动后健康检查失败端口占用或依赖未初始化先本机 curl /health检查环境变量查看启动日志6.1 常见误区Token 不是越省越好很多开发者在写 Prompt 时追求“极简”几乎不给模型任何上下文。这在传统编程里是合理的但在 LLM 应用里反而增加幻觉概率。系统提示词应包含角色、规则、示例、输出格式要求。它消耗的 Token 不算浪费而是引导成本。6.2 常见误区直接在生产环境用非确定性参数如果业务需要稳定输出格式比如解析关键字段应该尽量设置temperature0使用结构化输出功能提前做多轮测试评估输出格式失败率输出失败时提供降级方案比如返回错误码而不是空白。7. 最佳实践与工程建议7.1 安全边界AI 应用往往容易被忽略的是安全问题。项目落地时我建议至少做好这几件事API Key 管理不要硬编码在代码里使用环境变量或密钥管理服务。前端页面永不直接暴露模型 key。敏感数据脱敏如果模型服务在云端客户姓名、手机号、身份证等字段必须先脱敏再发送。输出内容限制在系统 Prompt 和响应侧都增加内容安全过滤。不要假设模型一定不会输出违规内容。工具调用权限Agent 如果需要操作数据库、发送消息、修改订单必须做权限控制和人工审批。7.2 配置管理模型服务配置建议单独管理model: provider: openai-compatible base_url: ${LLM_BASE_URL} api_key: ${LLM_API_KEY} name: qwen2.5:7b temperature: 0.7 max_tokens: 2048 timeout: 60 rag: top_k: 5 embedding_model: bge-large-zh好的实践是不同环境dev/staging/prod使用不同的 key 和模型地址避免本地调试误打到生产模型也避免生产请求消耗到个人测试 key。7.3 日志与可观测性与 LLM 相关的日志需要额外记录用户输入的原始内容Prompt 构建后的完整内容模型返回的原始内容Prompt 和 completion 的 token 用量请求耗时模型名和参数配置。这样当线上出现“答非所问”或“返回空内容”时我们可以快速定位是 Prompt 问题、模型问题还是代码问题。7.4 成本控制大模型调用成本波动很大尤其在生产环境要关注设置单用户每日调用上限长时间文本生成使用流式响应避免用户等待时超时对重复内容做缓存例如常见 FAQ 问题可以直接命中缓存对长上下文任务评估 token 消耗控制回忆窗口小任务用便宜模型复杂任务用强模型。7.5 模型与 Prompt 的版本管理这其实是很多 AI 项目后期最头疼的问题。如果线上 Prompt 改了但没记录模型返回结果变化时根本找不到原因。推荐做法Prompt 使用单独文件维护标注版本号模型名称和 Prompt 版本写入日志上线前用同一批评测用例对比新旧 Prompt 的输出差异重要 Prompt 变更时走评审和灰度流程。8. 总结与学习路线Move 37 真正的意义不在于“AI 下了一手好棋”而在于它改变了人们面对未知问题时的判断方式人类经验不是唯一路径高维搜索和策略推理同样能找到答案。今天做 AI 工程化也类似。我们不再需要把所有业务逻辑硬编码成规则而是可以让模型参与理解、决策、生成再通过工程手段确保质量、安全与成本可控。如果你想进一步深入建议按这个顺序学习先把模型调用链路跑通API 调用、Prompt 设计、温度参数调整。再掌握服务化FastAPI、Docker、流式输出、鉴权限流。然后学习 Agent 编排工具调用、状态管理、记忆机制。之后补 RAG向量化、召回、重排序、知识库管理。最后接触微调数据准备、训练、评测、A/B 验证。在整个过程中推荐动手做一个端到端小项目比如本文的会议纪要助手或者一个客服知识库问答系统。只要跑通一轮再去阅读 LangChain、Spring AI 等框架源码你会发现自己对 AI 工程的理解会更扎实。如果本文对你有帮助建议收藏备用。后续也可以继续关注 Agent 工程化、模型部署和高频排错相关主题我会在后面的文章里继续展开。