最新资讯
bloomberg.com Nvidia 加强东南亚芯片追踪以打击走私 thestack.technology 模型路由需求升温,Agent Router 推出开源替代方案 www.youtube.com Google DeepMind 的 Philipp Schmid:AI 同事需要具备的七个要素 unite.ai Cashfree 为 AI Agent 的托管结账加入 WebMCP 工具 dev.to 我们在 DolphinBench 上测试记忆检索:纯关键词搜索暴露了自身回归 dev.to 别再把 Agent 写成 while 循环,把它建模为状态机 analyticsindiamag.com 小语言模型可能重塑企业 AI 部署方式 bloomberg.com Rightmove 与 Scout24 借 AI 产品应对低迷房市并上调展望 stackoverflow.blog 欢迎来到芯片时代:半导体制造、AI 数据中心与芯片设计的未来 www.youtube.com AI Agent 总犯同样的错:CentralAgent AI 将记忆重构为经验系统 pub.towardsai.net Netflix 科学家建议重采样 LLM 评判:5 次仅将误差棒缩小 13% pub.towardsai.net Jev 作为 LLM 前的静默层:构建提示感知的模型路由器
多元动态
登录 注册
智能体 dev.to · @Hossein Hezami

AI Agent 应在不询问你的情况下被允许做什么?

原文 我的收藏

文章以 Agent 发现部署失败、读取日志、定位坏提交并起草回滚为例,提出关键问题不是 Agent 有多聪明,而是哪些动作可安全预授权、哪些需要显式审批、哪些应被禁止。作者主张低风险、可逆、私有、有边界的动作可不询问;外部、不可逆、昂贵、特权、批量、法律敏感或社会可见的动作应先询问。不应依赖模型“小心行事”,而应在应用层强制权限,并采用 observe→analyze→propose→draft→execute→publish→destroy 的风险阶梯;读取操作在特定情况下也可能危险。

AI推荐理由 把 Agent 自主性归结为权限设计问题,给出可预授权与需审批动作的划分原则及 observe→analyze→propose→draft→execute→publish→destroy 风险阶梯,并强调在应用层强制权限而非依赖模型自觉;对 Agent 落地治理有直接参考价值,属观点性框架而非实证研究。

76

正文

Your agent notices a failing deployment. It reads the logs, identifies the bad commit, drafts a rollback, and now wants to apply it. Should it just do it? If it asks for permission at every step, it becomes an expensive autocomplete. If it can do anything it can describe, it becomes a liability. The useful question is not “How smart is the agent?” It is: Which actions are safe to pre-authorize, which actions need explicit approval, and which actions should be impossible? That is not a prompt engineering problem. It is a permission design problem. TL;DR An AI agent should be allowed to do low-risk, reversible, private, bounded actions without asking. It should ask before doing anything external, irreversible, expensive, privileged, bulk, legally sensitive, or socially visible. Do not rely on the model to “be careful.” Enforce permissions in your application layer. Use a risk ladder: observe → analyze → propose → draft → execute → publish → destroy. Reads can still be dangerous if they expose secrets, PII, or data the agent can leak. Budgets, rate limits, scopes, and audit logs are part of the permission system. The safest architecture separates agent intent from action authorization. 📋 Table of Contents The real problem: autonomy without authority design 1. “Be Careful” Is Not a Permission Model 2. Use a Risk Ladder, Not a Flat Tool List 3. Reads Are Not Automatically Safe 4. Drafts and Private Writes Are Usually Fine 5. Ask When the Action Crosses a Boundary 6. Budgets and Rate Limits Are Permissions Over Time 7. “Notify Me” Is Not the Same as “Ask Me” 8. Never Let the Agent Grant Itself More Power 9. The Production Pattern: Policy, Audit, and Escape Hatches A practical rule for deciding what to pre-authorize The real problem: autonomy without authority design Most teams start with one of two bad defaults. The first is maximum caution: the agent must ask before everything. That feels safe, but it destroys the value of the agent. If every file read, search query, or draft suggestion requires approval, the human becomes the bottleneck. The second is maximum convenience: the agent gets broad tool access because it is “good at knowing what to do.” That works until the agent misinterprets a request, hits an edge case, follows a poisoned instruction, or performs an action the user never meant. The better approach is to classify actions by risk. An agent can often do these without asking: read non-sensitive logs search internal documentation summarize a file draft a pull request description create a local plan run a read-only query against a scoped replica generate a test in a sandbox An agent should usually ask before doing these: sending an email to a customer publishing a blog post deleting a database record deploying to production refunding a payment inviting a new admin changing IAM permissions contacting an external API that costs money performing a bulk mutation across many records The distinction is not whether the agent is confident. The distinction is whether the action is reversible, bounded, private, and expected. 1. “Be Careful” Is Not a Permission Model Scenario: Your system prompt says, “Only take safe actions. Ask before doing anything destructive.” The agent has a delete_repository tool. One day, it decides a repository is no longer needed. Why it matters: Language model behavior is probabilistic. Prompt instructions influence the agent, but they do not guarantee enforcement. If the tool is available and the agent chooses it, the action may happen. A safe agent system needs an authorization layer outside the model. Solution: Treat every agent action as a permissioned API call. The agent can propose an action, but your system decides whether the action is allowed, requires approval, or is denied. type RiskClass = | "read_public" | "read_sensitive" | "write_draft" | "write_internal" | "external_communication" | "financial" | "destructive" | "privilege_change"; interface AgentActionRequest { agentId: string; userId: string; action: string; risk: RiskClass; resource: string; estimatedCost?: number; context: Record; } interface AuthorizationDecision { allow: boolean; approvalRequired?: boolean; reason?: string; } async function authorizeAgentAction( req: AgentActionRequest ): Promise { const policy = await policyStore.forUserAndAgent(req.userId, req.agentId); if (policy.isDenied(req)) { return { allow: false, reason: "Denied by policy" }; } if (policy.requiresApproval(req)) { return { allow: false, approvalRequired: true }; } if (!(await withinBudget(req))) { return { allow: false, reason: "Budget exceeded" }; } return { allow: true }; } Enter fullscreen mode Exit fullscreen mode Why this works: The model is no longer the final authority. It can suggest delete_repository, but the policy engine can deny it regardless of how persuasive the model’s reasoning is. 🚨 Production warning: If your agent’s safety depends on the system prompt, you do not have safety controls. You have hopeful wording. 2. Use a Risk Ladder, Not a Flat Tool List Scenario: You review agent permissions by looking at a list of tool names: read_logs, create_ticket, send_email, restart_service, delete_branch. Some are obviously dangerous. Others seem harmless. But tool names do not tell you the real risk. Why it matters: A flat tool list hides the important question: what kind of effect does this action have on the world? create_ticket can be harmless if it creates a draft. It can be noisy if it creates a real ticket in a production tracker. It can be serious if it pages on-call at 3 a.m. Solution: Classify actions on a risk ladder. Stage Example Default treatment Observe Read public docs, list files Usually allowed Analyze Summarize logs, compare diffs Usually allowed Propose Suggest a fix, draft a plan Usually allowed Draft Create draft PR, draft ticket, local branch Usually allowed if private Execute internal Update staging config, create internal ticket Allowed with limits Publish Merge PR, publish page, deploy Usually approval Externalize Email customer, post to Slack channel, call partner API Usually approval Spend Buy credits, refund payment, provision paid resources Approval plus budget Destroy Delete record, drop table, terminate instance Strong approval or impossible Change permissions Add admin, modify scopes, change policy Almost always approval This gives you a more stable mental model than tool names. For example: risk_ladder: allow_without_asking: - observe - analyze - propose - draft_private allow_with_limits: - write_staging - create_internal_ticket require_approval: - publish - external_communication - spend - destructive - privilege_change deny: - self_permission_change - policy_modification - bulk_delete_unscoped Enter fullscreen mode Exit fullscreen mode Why this works: You are authorizing effects, not names. A new tool can be added later, but if its effect is “external communication,” it still lands in the approval bucket. 💡 Practical note: When adding a new agent tool, ask: “What is the worst plausible effect if this is called at the wrong time?” Then map that effect to the ladder. 3. Reads Are Not Automatically Safe Scenario: Your agent can read your issue tracker, internal wiki, and customer support database. It is only “reading,” so you allow it. Then a user asks it to summarize a customer issue. The agent includes an API key, internal email, or medical detail in the summary. Why it matters: Read access is still access. If the agent can read sensitive data, it can repeat, transform, summarize, or exfiltrate that data — intentionally or accidentally. This is especially important when the agent can: send messages create public artifacts call external tools write to shared documents generate links or reports operate on untrusted input A read-only action can become a data-leak path. Solution: Apply data classification and field-level filtering before information reaches the agent. interface CustomerRecord { id: string; name: string; email: string; paymentMethod?: string; supportNotes?: string; ssnLast4?: string; } function sanitizeCustomerForAgent( record: CustomerRecord, policy: DataPolicy ): Partial { return { id: record.id, name: policy.canSeePII ? record.name : redact(record.name), email: policy.canSeePII ? record.email : redact(record.email), supportNotes: policy.canSeeSupportNotes ? record.supportNotes : "Support notes unavailable for this agent.", }; } function redact(value: string): string { return `[redacted:${value.length}]`; } Enter fullscreen mode Exit fullscreen mode The important part is that redaction happens before the agent sees the record, not after. Why this works: You reduce the agent’s blast radius. Even if the model is tricked, misused, or overly chatty, it cannot reveal data it never received. ⚠️ Gotcha: “Read-only” is a database property, not a safety property. If the agent can read secrets and then write to a public channel, read access becomes an exfiltration route. 4. Drafts and Private Writes Are Usually Fine Scenario: Your agent wants to create a branch, write a proposed migration, open a draft pull request, or prepare a support response. You are unsure whether these writes should require approval. Why it matters: If every small write requires approval, the agent becomes slow and annoying. But if the agent can publish or execute immediately, mistakes become visible too fast. Solution: Pre-authorize writes that are: private reversible bounded not externally visible not financially consequential not security-sensitive Examples: create a draft branch create a draft document generate a test file in a sandbox write a local plan create an internal note prepare a patch draft a ticket response update a staging-only record A useful pattern is to make the agent’s first write always produce a pending artifact: interface DraftPullRequest { id: string; title: string; body: string; branch: string; status: "draft"; createdBy: "agent"; requiresHumanReview: true; } async function agentCreatesDraftPr(input: { repo: string; branch: string; title: string; body: string; }) { return prService.create({ repo: input.repo, branch: input.branch, title: input.title, body: input.body, draft: true, metadata: { createdBy: "agent", requiresHumanReview: true, }, }); } Enter fullscreen mode Exit fullscreen mode Why this works: The agent can make progress without forcing a human to approve every microstep. The human reviews the artifact before it becomes real. This is one of the best autonomy patterns: let the agent do the work, but make the result inherently reviewable. 🧠 The important part: Drafts are powerful because they separate labor from commitment. The agent can do the labor. A human or policy can control the commitment. 5. Ask When the Action Crosses a Boundary Scenario: The agent is asked to “clean up old customer accounts.” It finds 3,000 inactive accounts and prepares a deletion batch. The user meant “mark inactive,” not “delete.” Why it matters: Some actions are not dangerous because they are technically complex. They are dangerous because they cross a boundary: from private to public, from reversible to irreversible, from cheap to expensive, from internal to external. The approval question is really a boundary question. Solution: Require approval when an action crosses one of these boundaries: External visibility email customer post to Slack channel publish article create public comment send webhook to partner Irreversibility delete record terminate instance revoke token cancel subscription merge without rollback plan Financial impact refund payment buy credits provision paid resources upgrade plan trigger billable API Privilege escalation add admin change OAuth scopes modify IAM policy install app with broad permissions Bulk impact update all users delete stale records migrate production table send campaign to 50,000 recipients A policy gate can look like this: function requiresApproval(req: AgentActionRequest): boolean { if (req.risk === "external_communication") return true; if (req.risk === "financial") return true; if (req.risk === "destructive") return true; if (req.risk === "privilege_change") return true; if (req.context.bulk === true) return true; if (req.context.environment === "production" && req.action.includes("delete")) { return true; } return false; } Enter fullscreen mode Exit fullscreen mode Why this works: You are not asking the model to judge every situation. You are encoding boundaries that your organization already understands. 🔍 Why this matters: Approval should be triggered by the nature of the action, not by the model’s confidence. Confidence is not authority. 6. Budgets and Rate Limits Are Permissions Over Time Scenario: Your agent is allowed to call a search API, run code in a sandbox, and retry failed steps. Individually, each action seems safe. But a bug causes it to retry in a loop. Within an hour, it has burned through API credits and created hundreds of duplicate artifacts. Why it matters: A single action can be safe while the cumulative behavior is unsafe. Permissions need to account for frequency, volume, and cost. An agent that can spend $0.05 per action is not safe if it can perform 100,000 actions. Solution: Attach budgets and rate limits to agent capabilities. interface BudgetState { agentId: string; day: string; estimatedCostUsd: number; toolCalls: number; } async function withinBudget(req: AgentActionRequest): Promise { const budget = await budgetStore.get(req.agentId); const estimatedCost = req.estimatedCost ?? 0; if (budget.toolCalls + 1 > policy.maxToolCallsPerDay) { return false; } if (budget.estimatedCostUsd + estimatedCost > policy.maxDailyCostUsd) { return false; } return true; } Enter fullscreen mode Exit fullscreen mode For rate limits: async function withinRateLimit(req: AgentActionRequest): Promise { const key = `rate:${req.agentId}:${req.action}`; const count = await rateLimiter.increment(key, { window: "1m" }); return count <= policy.maxCallsPerMinute(req.action); } Enter fullscreen mode Exit fullscreen mode Why this works: You are treating autonomy as a bounded resource. The agent can act without asking, but only within a container of acceptable consumption. This is especially important for agents that can: call paid model APIs run compute-heavy jobs provision cloud resources send messages scrape external sites retry automatically spawn sub-agents 💡 Practical note: If an agent can retry, it needs a circuit breaker. Unlimited retries turn small mistakes into expensive incidents. 7. “Notify Me” Is Not the Same as “Ask Me” Scenario: Your agent sends a message saying, “I deleted the stale staging environment.” The user sees the notification two hours later. The environment contained a database seed needed for a demo. Why it matters: There is a big difference between: blocking until the user approves notifying the user after the action logging the action silently Many systems blur these together. They say the agent “asked” when it really just announced. Solution: Be explicit about the approval mode. type ApprovalMode = | "allow" | "notify_after" | "require_approval_before" | "deny"; interface ApprovalRequest { runId: string; agentId: string; userId: string; action: AgentActionRequest; mode: ApprovalMode; expiresAt: string; } async function handleAction(req: AgentActionRequest, runId: string) { const decision = await authorizeAgentAction(req); if (decision.allow) { return executeAction(req); } if (decision.approvalRequired) { const approval = await approvalStore.create({ runId, agentId: req.agentId, userId: req.userId, action: req, mode: "require_approval_before", expiresAt: new Date(Date.now() + 30 * 60_000).toISOString(), }); await runStore.pause(runId, approval.id); return { status: "waiting_for_approval", approvalId: approval.id, }; } throw new Error(decision.reason ?? "Action denied"); } Enter fullscreen mode Exit fullscreen mode Now the run can pause until approval arrives. Why this works: The system distinguishes between actions that can proceed, actions that need a human gate, and actions that merely deserve a record. Useful defaults: Action type Best mode Read public docs Allow Summarize internal data Allow or notify Create draft PR Allow Create real ticket Notify or approval depending on impact Send customer email Require approval before Delete production data Require approval before or deny Change permissions Require approval before Spend money Require approval before ⚠️ Gotcha: If the action cannot be undone, notifying afterward is not the same as consent. 8. Never Let the Agent Grant Itself More Power Scenario: Your agent can manage tools, install plugins, update its own configuration, or request new OAuth scopes. It encounters a task it cannot complete, so it tries to expand its permissions. Why it matters: This is the permission equivalent of giving a program sudo because it asked nicely. If an agent can modify its own authority, the entire permission model collapses. This risk shows up in several forms: the agent installs a new MCP server or plugin the agent requests broader API scopes the agent updates its own policy file the agent creates a new admin user the agent writes a workflow that runs with higher privileges the agent asks another agent with more permissions to perform the action Solution: Make permission changes a protected human action by default. const PROTECTED_ACTIONS = new Set([ "policy.update", "agent.scope.grant", "oauth.scope.request", "user.role.promote", "tool.install", "mcp_server.register", "workflow.privilege.escalate", ]); function isProtectedAction(action: string): boolean { return PROTECTED_ACTIONS.has(action); } async function authorizeProtectedAction(req: AgentActionRequest) { if (isProtectedAction(req.action)) { if (req.context.requestedBy === req.agentId) { return { allow: false, reason: "Agents cannot modify their own privileges", }; } return { allow: false, approvalRequired: true, reason: "Privilege changes require human approval", }; } return authorizeAgentAction(req); } Enter fullscreen mode Exit fullscreen mode Why this works: You prevent the agent from becoming a privilege-escalation vector. Even if the agent is compromised, confused, or manipulated by untrusted input, it cannot directly widen its own authority. 🚨 Production warning: Watch out for indirect escalation. If Agent A can ask Agent B to do something, and Agent B has broader permissions, you need to evaluate the full delegation chain. 9. The Production Pattern: Policy, Audit, and Escape Hatches The safest agent systems I’d design do not try to make the agent perfectly wise. They make the system legible and controllable. A practical production architecture looks like this: User request ↓ Agent planner ↓ Proposed action ↓ Policy engine ↓ Budget/rate check ↓ Approval gate if needed ↓ Tool execution layer ↓ Audit log ↓ User notification / UI Enter fullscreen mode Exit fullscreen mode The important components are: Policy engine Decides whether an action is allowed, denied, or needs approval. default: deny rules: - allow: action: logs.read environment: staging - allow: action: pull_request.create_draft repo_visibility: internal - require_approval: action: email.send recipient_type: external - require_approval: action: payment.refund when: amount_cents_gt: 10000 - deny: action: policy.update requested_by: agent Enter fullscreen mode Exit fullscreen mode Execution layer Performs the actual tool call only after authorization. Audit log Records: who requested the action which agent proposed it what policy applied what approval was given what arguments were used what result occurred what cost was incurred Escape hatch Lets a human pause, cancel, or roll back the agent. await runStore.cancel(runId, { reason: "user_requested", cancelledBy: userId, }); Enter fullscreen mode Exit fullscreen mode Why this works: You are not asking the model to be the security boundary. You are building a system where the model can be useful without being omnipotent. A practical rule for deciding what to pre-authorize If I had to reduce the decision to one rule, it would be this: An AI agent may act without asking when the action is low-risk, reversible, bounded, private, auditable, and within a pre-approved budget. If any of those are false, pause. More concretely, I would allow an agent to act without asking when all of these are true: The action does not affect external users. The action does not spend significant money. The action does not delete or overwrite important data. The action does not change permissions. The action is scoped to a single resource or small batch. The action can be reviewed or undone. The action does not expose sensitive data. The action is within rate and cost limits. The user would reasonably expect the agent to do it. I would require approval when any of these are true: The action sends something to a human. The action publishes something publicly. The action affects production. The action costs meaningful money. The action is hard or impossible to reverse. The action changes access control. The action touches regulated or highly sensitive data. The action affects many records at once. The action was derived from untrusted content. The last one deserves emphasis. If the agent read an email, issue comment, web page, or document that could contain hostile instructions, you should be more cautious about letting it take privileged actions immediately afterward. The goal is not to make agents passive. The goal is to make their autonomy legible. A good agent permission system feels like a well-designed employee role: enough access to be useful not enough access to cause a disaster clear escalation paths a complete record of what happened The agent should not be trusted because it sounds confident. It should be allowed because your system has already decided that this class of action is safe.

来源报道 · 1 篇 · 以下链接均前往原始媒体

← 返回精选动态 原文

更多内容