为什么你的 Agent 上线就崩?因为 Demo 阶段你根本不需要权限

为什么你的 Agent 上线就崩?因为 Demo 阶段你根本不需要权限 如果你正准备往大模型方向转《Agentic AI怎么学先做一个会暴露问题的真实项目》这类问题别只看热度。更重要的是判断自己该补哪块能力以及怎么证明你真的会。摘要先把这篇文章的目标说清楚看完之后你应该能判断这件事值不值得做以及从哪里动手。最近在看几个大模型应用项目的复盘发现一个挺有意思的现象大家在写简历或者做技术分享时热衷于展示 Agent 多么“聪明”能自动拆解任务、调用 API、甚至自我修正。但在实际的生产环境评审中评委或者说是负责运维和安全的技术负责人往往只问三个问题谁能调用什么操作记录在哪里出错了谁来兜底如果你回答不上来那这个 Agent 无论演示得多花哨在工程视角下都只是一个玩具。今天不想聊那些宏大的 Agentic AI 架构理论我想结合我最近的一个内部重构项目聊聊为什么从 Demo 到生产权限管控和可观测性才是真正的分水岭。这也是很多初级 AI 工程师转型时最容易忽略的“脏活累活”。目录从“全能神”到“受控者”自主性的边界任务拆解与工具调用的工程化实现可观测性当 Agent “黑盒”运行时总结从“能跑”到“敢用”从“全能神”到“受控者”自主性的边界很多初学者做 Agent 的第一反应是“我要让它尽可能自主”。于是我们赋予它搜索网页、读写数据库、修改配置的权力。在本地跑通确实爽但一旦进入团队协作或生产环境这种“全能”就是灾难。在我最近负责的内部知识库问答系统中最初版本的 Agent 可以直接通过 Python 代码解释器执行任意 SQL 查询。Demo 阶段用户问“过去一周销量最高的商品”Agent 瞬间给出结果体验极佳。然而当接入正式测试环境时问题暴露了1. 数据安全Agent 可以DROP TABLE虽然概率低但后果不可接受。2. 性能黑洞一次复杂的关联查询可能导致数据库锁表影响其他正常业务。3. 责任不清当数据出错时是模型幻觉还是 SQL 写错了还是底层数据源有问题如果没有详细的执行日志和权限隔离排查成本极高。我的取舍策略我将 Agent 的能力从“直接执行”改为“受限生成”。它不再直接连接数据库而是生成符合特定 Schema 的查询语句。这些语句必须经过一个中间件Middleware进行语法校验和权限过滤。只有被白名单允许的表和操作类型如 SELECT禁止 UPDATE/DELETE才会被执行。这种转变看似降低了 Agent 的“智能感”实则提升了系统的可控性。在生产环境中安全约束不是功能的对立面而是功能存在的基石。任务拆解与工具调用的工程化实现既然限制了直接执行那么 Agent 如何完成复杂任务这就需要精细的工具定义和调用逻辑。这里我展示一个基于 LangChain 风格的伪代码示例重点在于工具定义的严谨性和异常处理的结构化。from typing import List from langchain_core.tools import tool from langchain_core.messages import HumanMessage, AIMessage # 1. 定义安全的工具接口注意不使用 tool 装饰器简单包裹而是显式控制输入输出 tool def search_knowledge_base(query: str, max_results: int 5) - List[str]: 搜索知识库仅限只读操作。 参数必须限制数量防止大模型无节制请求导致服务过载。 if max_results 20: return [Error: Query limit exceeded. Please reduce max_results.] # 模拟数据库查询 # 在实际工程中这里应该连接的是经过权限校验的视图而非直接表 results db.execute_safe_query(query, read_onlyTrue) return [res.content for res in results] tool def update_user_profile(user_id: str, field: str, value: str) - dict: 更新用户信息。 关键约束field 必须在白名单内value 需要二次确认。 allowed_fields [bio, nickname, avatar_url] if field not in allowed_fields: return {status: denied, reason: fField {field} is not allowed for modification.} # 执行更新... return {status: success, updated_field: field} # 2. 在 Agent 循环中注入可观测性 class ObservableAgent: def __init__(self, tools): self.tools tools self.log_history [] def run_with_observability(self, query: str): print(f[START] User Query: {query}) try: # 模拟 Agent 推理过程 # 实际项目中这里会调用 LLM 选择工具 selected_tool self.tools[0] # 假设选择了 search_knowledge_base # 执行前记录 self.log_history.append({ event: tool_invocation_start, tool_name: selected_tool.name, input: query }) result selected_tool.run(query) # 执行后记录 self.log_history.append({ event: tool_invocation_end, tool_name: selected_tool.name, output_length: len(result) }) print(f[END] Result: {result}) return result except Exception as e: # 捕获异常并记录而不是直接崩溃 self.log_history.append({ event: error, message: str(e) }) raise e这段代码虽然简单但体现了几个关键点1. 最小权限原则update_user_profile限制了可修改字段。2. 资源保护search_knowledge_base限制了最大返回结果数。3. 结构化日志通过ObservableAgent将工具调用的起止、输入输出记录下来。这在调试时比打印一堆print()有用得多。可观测性当 Agent “黑盒”运行时很多人认为有了日志就能 Debug。其实不然。LLM 产生的中间思考过程Thought Process往往是非结构化的文本传统的日志系统很难从中提取价值。在我的重构项目中我们引入了Trace ID和结构化事件流。每次用户请求分配一个唯一的trace_id。LLM 的每一次 Token 生成、每一个工具调用、每一次自我反思都作为独立事件记录下来并关联到该trace_id。这样做的好处是当线上出现一个糟糕的回答时你可以回溯整个决策链路是 Prompt 没写好是检索到的文档质量差还是模型在推理过程中发生了“幻觉漂移”如果没有这些可观测性数据你只能对着用户的一句“这答案不对”干瞪眼。而在真正跑起来中可观测性决定了系统的维护成本。对于一个无法监控的 Agent无论其初始性能多好随着迭代次数增加它的表现往往会退化。总结从“能跑”到“敢用”回到最初的问题为什么很多 Agent 项目止步于 Demo因为 Demo 追求的是惊喜感而生产追求的是确定性。Demo 阶段你可以硬编码一些特例忽略异常路径假设模型永远正确。生产阶段你必须假设模型会犯错会越权会超时。作为开发者在构建 Agentic AI 系统时建议按照以下优先级投入精力1. 权限与安全明确 Agent 能做什么不能做什么。这是红线。2. 可观测性与日志确保每一次决策都可追溯。这是调试的基础。3. 错误恢复机制当工具调用失败或模型输出异常时系统能否优雅降级4. 任务拆解与规划这才是体现 Agent 智能的地方但前提是前两者稳固。不要沉迷于让 Agent 表现得像一个全知全能的神。让它成为一个守规矩、有记录、知进退的数字员工这才是它在企业环境中生存下来的唯一方式。如果你正在准备 AI 相关的求职或项目复盘记住面试官更想知道你如何处理一个失败的 Tool Call而不是你如何设计一个完美的 Prompt。资料展示下面是我整理的AI大模型学习资料和工具包预览适合收藏后按主题逐步学习。如果你想看完整资料目录可以在评论区留言「资料」也欢迎告诉我你更关注AI大模型里的哪类内容。