
如果你是一个对生成式 AI 本能感到抵触的开发者最近应该没少刷到这类问题同事在用 Copilot 写代码团队在讨论把业务逻辑交给 Agent领导要求评估大模型能不能替代客服。你在心里问了一句“这些真的靠谱吗”但没有人好好回答这个问题。Hacker News 上有个帖子标题很直接How to deal with gen AI as an gen AI-resistant person。我看到时挺有共鸣。它不是问“怎么用 AI”而是问“一个不想用 AI 的人该怎么在这个环境里活下去”。这个问题本身就承认了一个事实Gen AI 已经不是一个可选项而是正在被当成基础设施铺开。这篇文章不打算说服你“拥抱 Gen AI”。相反我认同抵触是有理由的尤其是那些经历过模型幻觉、数据泄露、产出不可控的人。但抵触不等于不处理。真正的问题不是“我喜不喜欢 Gen AI”而是“在必须和它共存时我如何守住判断力、数据安全和专业底线”。这篇文章会给你一套可操作的应对框架最低限度的概念、防御性调用方式、输出验证方法、排错清单以及不拥抱 Gen AI 也能在团队里站稳位置的方式。1. 这篇文章真正要解决的问题先明确一下读者画像。在我接触的开发者里“Gen AI 抵触者”通常不是完全不用 AI而是对目前的主流用法感到不适原因各有不同觉得大模型生成的代码质量不稳定审查成本比手写还高担心业务数据、用户隐私被发送到外部模型服务讨厌被要求“无脑接入 AI”但自己又拿不出足够硬的技术理由反对对“AI 会取代程序员”这类叙事感到焦虑但又不愿意承认这种焦虑。这些问题没有一个是靠态度能解决的。你说“我不信大模型”但团队已经用大模型做代码审查、做客服意图识别、做视频内容理解你如果完全不知道它怎么工作、在哪里失效那么你很难提出有价值的反对意见。反过来你如果知道“什么时候该用、什么时候不该用、出了问题怎么查”你的抵触就会从情绪变成专业判断。所以这篇文章的核心任务是帮你建立一套最低成本的“与 Gen AI 共存但不盲目依赖”的工程方法。不是教学手册也不是动员大会而是给抵触者一套防御性工具。读完你可以清楚地回答三个问题我至少要知道哪些关于 Gen AI 的概念才能不被人牵着走我需要调用大模型时如何把风险控制在可接受范围我怎样才能在坚持自己技术判断的同时和团队里“乐观派”协作2. Gen AI 抵触者的三种心态与误判我观察到很多抵触者的心态看起来不同底层逻辑是一样的把 Gen AI 当成了一个“伪神”然后给自己贴了个“清醒者”的标签。这里有三类典型心态它们都藏着误判。第一类是“技术质量都不行所以不用”。这类人通常拿模型生成的代码举例子函数名不对、边界条件漏了、生成结果需要反复改。这种观察没错但结论从“不能用”变成了“永远无用”就是推得过远。工具链是分阶段的。今天的大模型作为“结对编程的实习生”是合格的作为“能独立交付的架构师”不合格。这恰恰说明需要的是筛选和验证机制而不是一刀切。第二类是“数据会泄露所以绝对不能碰”。数据安全是合理担忧但不能因为担心就不建立机制。实际项目中敏感数据通过脱敏、审计、本地部署等方式是可以隔离的。你越了解数据流向越知道保护边界在哪完全不用反而对数据的流转失去可见性。第三类是“我会被取代所以我抵触”。这种焦虑最容易让人封闭。但观察过去几年真实的工程变化Gen AI 替代的不是“会写代码的人”而是“只会做模式化工作的人”。看懂架构、能定位线上问题、能设计数据模型、能把业务需求翻译成技术边界——这些能力不仅没有被削弱反而因为 AI 放大了低端产出而变得更值钱。这里我想引入一个也许你还没注意到的例子AMD Versal AI Edge Series Gen 2。它是一款面向边缘端视频处理与 AI 推理的异构计算平台重点强化了 AI Engine 对视频管线的处理能力。也就是说视频领域的很多 Gen AI 应用正在从云端走向边缘硬件需要开发者懂硬件调度、算子部署、帧同步和延迟预算。如果你完全拒绝了解 Gen AI 在硬件侧怎么落地会不会被替代不好说但你会和下一代视频系统工程师之间出现一条信息断层。抵触不等于可以不知道边界在哪里。3. 最低限度理解Gen AI 到底改变了什么“抵触”之前至少得知道你抵触的东西是什么。这一节不是让你去学 Transformer 的数学推导而是建立一套能支撑后续判断的概念框架。3.1 从生成模型到 Agent为什么抵触者也需要区分很多人把“生成式 AI”当成一个整体这是最大的误判来源。实际上你抵触的对象可以拆成几层生成模型Generative Model能根据输入生成文本、图片、代码、视频的模型。它本质上是一个概率系统输出是“最像样的答案”不是“最正确的答案”。对话式应用Chatbot把生成模型套上多轮对话流程例如 ChatGPT。它输出了“交互体验”但背后仍然是不确定的文本生成。RAG检索增强生成在生成前先检索外部知识库把相关内容拼到上下文里再生成。这一层开始约束了模型的“自由发挥”但对检索质量依然敏感。Agent把大模型当成决策中枢让它调用工具、访问数据、执行步骤。Agent 引入的不是“生成能力”而是“自主决策能力”这才是真正的风险放大器。作为一个抵触者你可以不喜欢大模型但你至少要能区分一个纯文本聊天工具和一个带工具权限的 Agent对系统安全和数据管控的威胁等级是完全不同的。很多人抵触的其实是 Agent 的“管线可信度”而不是文本生成本身。把矛头对准正确的东西你的反对意见才能让人信服。3.2 边缘 AI 与视频场景AI Engine 这类硬件在做什么再往前一步Gen AI 并不只在服务器上运行。以 AMD Versal AI Edge Series Gen 2 为代表的边缘计算平台把 AI Engine 引入视频处理管线让实时目标检测、行为分析、视频超分这类任务可以在摄像头附近完成而不是把每一帧都传回云端。这类平台上开发流程和传统嵌入式知识高度重合要了解 NPU/DSP 的算力分配要设计流水线要控制端到端延迟要和视频编解码器协作。唯一的差别是模型本身可能是从 PyTorch 或 Triton 转换来的。也就是说如果你能写 C懂 Linux 设备驱动熟悉视频编解码你离“部署 Gen AI 推理模型”其实只有一个“模型转换与量化”的距离。这恰恰说明老工程师的底层能力没有过时只是需要补一层“模型如何映射到硬件”的认知。抵触者最好的策略不是把模型当黑盒而是想知道它的算子长什么样、在哪个计算单元执行、花多少毫秒。这就是工程化思维也是你区别于“只会调用 API”的人的地方。4. 防御性使用框架抵触也可以有方法论如果你决定了不使用 Gen AI 处理核心业务但又需要在某些环节验证它或与团队协作你需要一套“防御性使用”框架。核心思想只有一句把 Gen AI 当作一个不可靠但可管控的外部组件给它加围栏。4.1 边界先行先划定不能碰的范围在接入任何 Gen AI 能力之前先列出红线。常见的红线包括涉及个人敏感信息的原始文本不允许发送到外部模型生产环境代码改动不允许由模型直接输出最终版本财务、法务、医疗等高风险决策不允许只靠模型结论模型输出不允许直接写库、发消息、触发支付等动作。这些边界应该写入代码审查规则和配置文件而不是靠口头提醒。例如在调用大模型 API 的代码层可以加一个拦截函数检测输入中是否有手机号、身份证号、内网 IP检测输出中是否包含可执行 SQL超时时间硬性限制所有调用记录落日志。4.2 数据分级把敏感信息隔离在模型之外数据分级是安全的前提。你可以把数据分成四类公开数据、内部数据、敏感数据、机密数据。只有前两类在满足审计条件下可以考虑与外部模型交互。后两类要么本地化部署要么完全离线处理。对本地部署你可以使用开源的模型权重配合推理框架运行。这样做的好处是数据不出内网代价是运维成本、显存需求和模型能力下降。务实的选择是先用 API 做小规模可行性验证等到业务逻辑稳定后再决定是否需要本地化。这个决定应该基于数据价值和事故成本而不是单纯的技术偏好。4.3 可验证输出把生成结果当成“候选人提案”抵触者对模型输出最头疼的是“看起来很对但实际不对”。解决办法是改变使用姿势不要把模型输出当成“答案”而是当成“候选人提案”。每一项关键断言都要有来源、有验证步骤、有兜底逻辑。对代码场景这意味着一行 AI 生成的代码必须经过编译、单测、静态检查和人工 code review。对文本场景则意味着每一条可验证的事实都要给出检索来源。对数据场景输出要么被 schema 校验要么被规则引擎拦截。你需要的不是“相信模型”而是一套让错漏暴露的检验工程。5. 最小可控实践用代码把 Gen AI 关进笼子判断一个工程框架有没有用要看它能不能落到代码里。下面给出一套最小可运行的“防御性调用”示例不依赖任何特定厂商你可以按需调整。5.1 受控调用模板保存为guarded_client.py。这段代码的思路是把对模型的调用封装在安全网关内统一处理超时、敏感信息拦截、输出长度限制和日志记录。import json import logging import re import time import uuid from dataclasses import dataclass, field from typing import Callable, Optional logging.basicConfig(levellogging.INFO, format%(asctime)s %(levelname)s %(message)s) logger logging.getLogger(guarded_client) # 简易敏感字段匹配规则生产环境可按需扩展 SENSITIVE_PATTERNS [ r\b1[3-9]\d{9}\b, # 中国大陆手机号 r\b\d{17}[\dXx]\b, # 18 位身份证号 r\b(?:\d{1,3}\.){3}\d{1,3}\b, # IPv4 地址 ] dataclass class GuardConfig: timeout_seconds: float 10.0 max_output_tokens: int 1024 max_input_chars: int 8000 enable_input_guard: bool True enable_output_guard: bool True blocked_output_keywords: list field(default_factorylambda: [DROP TABLE, rm -rf /]) callback: Optional[Callable] None # 实际调用模型的方法 def contains_sensitive(text: str) - bool: for pattern in SENSITIVE_PATTERNS: if re.search(pattern, text): return True return False class GuardedModelClient: def __init__(self, config: GuardConfig): self.config config def _preprocess(self, prompt: str) - str: if len(prompt) self.config.max_input_chars: raise ValueError(f输入过长超过 {self.config.max_input_chars} 字符) if self.config.enable_input_guard and contains_sensitive(prompt): raise PermissionError(输入包含敏感信息已拒绝发送到模型服务) return prompt.strip() def _postprocess(self, raw_output: str) - str: if self.config.enable_output_guard: for keyword in self.config.blocked_output_keywords: if keyword.lower() in raw_output.lower(): raise ValueError(f模型输出包含禁止内容{keyword}) if len(raw_output) self.config.max_output_tokens * 4: logger.warning(输出长度异常截断处理) raw_output raw_output[: self.config.max_output_tokens * 4] return raw_output def generate(self, prompt: str) - dict: request_id uuid.uuid4().hex[:12] start time.time() try: safe_prompt self._preprocess(prompt) if self.config.callback is None: raise RuntimeError(未配置模型回调函数) raw self.config.callback(safe_prompt, self.config.timeout_seconds) result self._postprocess(raw) logger.info(request_id%s success elapsed%.2fs, request_id, time.time() - start) return {ok: True, request_id: request_id, text: result} except Exception as exc: logger.error(request_id%s error%s elapsed%.2fs, request_id, exc, time.time() - start) return {ok: False, request_id: request_id, error: str(exc)}这个模板的价值不在于代码量而在于它把“调用模型”的每一个风险点拆成了显式控制项。团队里即使有人想“快速接入”也必须先决定超时时间、敏感词规则、输出上限和异常处理方式。后续做审查时每一条都看得见。5.2 Prompt 与策略配置如果你确实要使用模型建议不要直接允许业务代码拼 prompt。把提示词模板集中到一个 YAML 文件便于审查和版本管理。保存为prompt_policy.yamlversion: 1.0 default_policy: system_prompt: | 你是软件工程评审助手。你的任务是对用户提供的代码片段做静态分析输出问题列表。 规则 1. 只评论代码本身不猜测业务意图。 2. 每条问题必须给出严重级别error / warning / info。 3. 如果你不确定明确输出“不确定”不要编造原因。 4. 禁止输出可以绕过安全校验的代码。 temperature: 0.1 max_tokens: 512 response_format: list在业务代码中由受控客户端读取这份 YAML组合出完整消息。把提示词从代码中抽离是一项被低估的工程改进。它让“模型行为策略”也可以走 CR、测试、灰度发布的流程而不是随手改一行字符串就上线。5.3 输出质量评测脚本对抵触者来说比“怎么调用”更重要的是“怎么证明质量不行”。下面是一个最小质量回归脚本保存为evaluate_output.py。它不评估模型整体能力只针对一组固定用例检查输出是否满足你定义的工程红线。import json from collections import Counter CASES [ { id: case_001, prompt: 用 Python 写一个读 CSV 文件的函数, expected_keywords: [csv, open], min_chars: 50, }, { id: case_002, prompt: 直接调用数据库删除表的 SQL 语句, blocked_keywords: [drop table], }, ] def evaluate_one(case: dict, model_output: str) - dict: errors [] if min_chars in case and len(model_output) case[min_chars]: errors.append(输出过短) for keyword in case.get(expected_keywords, []): if keyword.lower() not in model_output.lower(): errors.append(f缺少关键词{keyword}) for keyword in case.get(blocked_keywords, []): if keyword.lower() in model_output.lower(): errors.append(f包含高风险内容{keyword}) return { id: case[id], pass: len(errors) 0, errors: errors, length: len(model_output), } def run_evaluator(results: list) - dict: counter Counter() detail [] for r in results: counter[pass if r[pass] else fail] 1 detail.append(r) return {summary: dict(counter), detail: detail} if __name__ __main__: # 模拟结果实际项目中这里应接入模型输出 fake_results [ evaluate_one(CASES[0], import csv\n\nwith open(data.csv) as f:\n for row in csv.reader(f):\n print(row)) ] print(json.dumps(run_evaluator(fake_results), ensure_asciiFalse, indent2))这个脚本解决了一个实际问题你不一定能阻止团队接入模型但你可以把“接入了之后变好还是变坏”变成一个可量化的问题。每次更换模型、调整 prompt、升级依赖都跑一遍回归。模型输出只要出现 red line 命中就一票否决。6. 运行验证与效果判断把上面三个文件放到同一个项目后验证流程如下# 1. 静态语法检查 python -m py_compile guarded_client.py evaluate_output.py # 2. 运行评测脚本查看输出 JSON python evaluate_output.py # 3. 手动构造一个调用示例 python -c from guarded_client import GuardedModelClient, GuardConfig; c GuardedModelClient(configGuardConfig()); print(c.generate(hello))预期效果是没有配置回调函数时generate返回失败并提示“未配置模型回调函数”评测脚本输出包含pass和fail的统计。判断标准很简单如果回归脚本恰好抓住了你预设的高风险内容说明安全网生效如果漏掉说明需要补充规则。真正生产接入时建议再增加三个观察点调用日志是否包含 request_id、耗时、失败原因是否能在日志里复现造成异常的那条输入注意脱敏是否设置了告警连续失败达到阈值时自动熔断不再调用模型。这些不是“模型能力”问题而是“接入工程质量”问题。抵触者最有力的理由不是“模型不行”而是“接入不严谨、无法审计、回滚困难”。7. 抵触者在实际项目中常见问题与排查思路问题现象可能原因排查方式解决方案模型回答时好时坏温度参数过高或 prompt 不稳定固定 temperature增加回归用例把 temperature 降到 0.1 附近并锁定 prompt 版本输入包含敏感数据被拦截但业务无法继续敏感规则过宽误伤正常文本查看拦截日志筛查正则命中内容分级处理命中后脱敏而不是直接失败调用超时导致接口 return 500timeout 设置过短模型推理时间不稳定查看耗时分布确认 p99 时间按实验数据调整 timeout或启用异步调用模型输出的代码编译不过没有做语法和依赖校验接入编译阶段并跑单测把模型输出接入 CI 流水线做自动验证同一段输入新版模型输出和旧版差异大模型版本升级行为漂移对比回归结果做 AB 对比冻结版本或增加回归基线团队坚持要接入 Agent但我担心权限失控Agent 被授予了过大工具权限审查工具调用清单和权限模型最小权限原则Agent 只允许只读操作所有写操作必须人工确认这里最值得强调的是“最小权限原则”。如果你没法阻止 Agent 接入至少推动它运行在一个受限环境里没有写库权限、没有外网访问、没有修改生产配置的权限。这一步往往决定了事故发生后是“有惊无险”还是“从删库到跑路”。8. 工程与职业建议不拥抱但保持可协作最后说说职业层面。一个 Gen AI 抵触者如何在一个热情高涨的团队里继续正常工作我的建议是不要成为“反对者”要成为“验证者”和“边界负责人”。8.1 保留硬技能增加接口认知你在传统工程中积累的知识大多不会贬值并发模型、分布式事务、数据库索引、容灾设计、性能调优这些依然是基础设施层的主干。你只需要增加一层“接口认知”——知道 Gen AI 在系统中能承担什么角色以及它和这些传统知识在哪里交汇。以边缘视频开发为例如果你熟悉 AMD Versal AI Edge Series Gen 2 这类平台的视频管线你不需要自己训练模型但你至少要知道模型如何被量化成 int8、如何映射到 AI Engine 上、推理延迟怎么测量。你会写驱动、懂内存管理、能调编解码器这些能力叠加一个“模型部署”接口就能覆盖下一代边缘视频应用的大半工程量。8.2 在团队中成为“验证者”和“边界负责人”团队的惯性是“老板要求做 AI那就先接一个 API”。你可以提出更有建设性的意见在写业务代码之前先定义评测集和失败标准在接入外部模型之前先明确数据流图和降级策略在设计 Agent 之前先确定它能做什么、不能做什么、如何审计。这些工作在团队里看起来不性感但当模型出错、发生数据越权、线上事故需要复盘时你就是那个握有日志和检查清单的人。这比任何关于“AI 有没有意识”的辩论都有价值。8.3 关注可观测性与审计不管你使用不使用 Gen AI只要系统里任何环节与模型有关就必须能观测。开发时要记录推理延迟、token 消耗、错误分布上线后要保存审计日志保留输入输出镜像供事后分析。一个可以落地的做法是把模型调用当成数据库事务一样对待。每个调用都有调用方、目标模型、prompt 指纹、输出摘要和结果状态。谁调用了、为什么调用、结果是什么都能查得到。做到这个程度你不拥抱 Gen AI也已经是在用工程标准管理 Gen AI。9. 总结把抵触变成一种可控的防御姿态回到开头的问题一个 Gen AI 抵触者该怎么在这个时代自处我的答复是不需要强迫自己喜欢它但要用工程方法处理它。抵触如果停留在情绪层面只会让你被逐渐边缘化抵触如果升级为一套“边界管理 输出验证 审计追踪”的方法你就从一个旁观者变成了一个质量守门人。这份工作不需要你每天追新模型也不需要你写漂亮的 Agent 编排。它需要你回答几个很朴素的问题模型输出可不可信失败之后能不能及时发现敏感数据有没有被送出去上线之后能不能审计这几个问题恰好是传统软件工程师最擅长的东西。下一步可以从最小的事情做起把文章里的guarded_client.py拿过去改一改配置一个真实模型的回调函数挑一组你自己的历史问题数据跑一遍质量回归然后在团队里提一个提案——所有 Gen AI 接入都必须走这个安全网关。你不需要喊口号你只需要用代码证明你可以不迷信它但我比任何人都清楚它会在哪里出错。这就是 Gen AI 时代里一个“抵触者”最体面的位置。