企业 Agent 需求怎么写:数据结构、流程图与 Python 校验

企业 Agent 需求如果只写「实现智能问答」「自动处理销售线索」,开发阶段很快会遇到边界问题:输入格式不稳定、工具权限不明确、异常无法复现、验收没有统一标准。

解决方法不是继续补功能列表,而是先建立一份机器可读的场景契约,把业务材料转换成数据结构和验证规则。

1. 场景契约的数据结构

一条场景至少包含六组信息:流程、样例、规则、系统权限、知识来源、验收与恢复。

yaml 复制代码
schema_version: "1.0"
scene_id: invoice_review
owner: finance_ops
trigger:
  event: invoice.uploaded
input:
  content_type: application/pdf
  sample_dir: fixtures/invoices/
  required_fields: [invoice_no, seller, buyer, amount]
output:
  schema: InvoiceReviewV1
  destination: finance.review_queue
rules:
  deterministic: [field_required, amount_range]
  model_assisted: [item_category, exception_summary]
permissions:
  read: [document_store, vendor_directory]
  write: [finance.review_queue]
  forbidden: [payment.create, invoice.approve]
knowledge:
  sources: [finance_policy, vendor_rules]
  version_required: true
human_gate:
  - confidence_below_threshold
  - vendor_conflict
  - amount_above_limit
acceptance:
  field_accuracy: 0.98
  p95_latency_seconds: 30
recovery:
  checkpoint: before_business_write

2. 从契约生成执行链

#mermaid-svg-MpFMk43GrMKpGaAO{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-MpFMk43GrMKpGaAO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-MpFMk43GrMKpGaAO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-MpFMk43GrMKpGaAO .error-icon{fill:#552222;}#mermaid-svg-MpFMk43GrMKpGaAO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-MpFMk43GrMKpGaAO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-MpFMk43GrMKpGaAO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-MpFMk43GrMKpGaAO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-MpFMk43GrMKpGaAO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-MpFMk43GrMKpGaAO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-MpFMk43GrMKpGaAO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-MpFMk43GrMKpGaAO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-MpFMk43GrMKpGaAO .marker.cross{stroke:#333333;}#mermaid-svg-MpFMk43GrMKpGaAO svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-MpFMk43GrMKpGaAO p{margin:0;}#mermaid-svg-MpFMk43GrMKpGaAO .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-MpFMk43GrMKpGaAO .cluster-label text{fill:#333;}#mermaid-svg-MpFMk43GrMKpGaAO .cluster-label span{color:#333;}#mermaid-svg-MpFMk43GrMKpGaAO .cluster-label span p{background-color:transparent;}#mermaid-svg-MpFMk43GrMKpGaAO .label text,#mermaid-svg-MpFMk43GrMKpGaAO span{fill:#333;color:#333;}#mermaid-svg-MpFMk43GrMKpGaAO .node rect,#mermaid-svg-MpFMk43GrMKpGaAO .node circle,#mermaid-svg-MpFMk43GrMKpGaAO .node ellipse,#mermaid-svg-MpFMk43GrMKpGaAO .node polygon,#mermaid-svg-MpFMk43GrMKpGaAO .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-MpFMk43GrMKpGaAO .rough-node .label text,#mermaid-svg-MpFMk43GrMKpGaAO .node .label text,#mermaid-svg-MpFMk43GrMKpGaAO .image-shape .label,#mermaid-svg-MpFMk43GrMKpGaAO .icon-shape .label{text-anchor:middle;}#mermaid-svg-MpFMk43GrMKpGaAO .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-MpFMk43GrMKpGaAO .rough-node .label,#mermaid-svg-MpFMk43GrMKpGaAO .node .label,#mermaid-svg-MpFMk43GrMKpGaAO .image-shape .label,#mermaid-svg-MpFMk43GrMKpGaAO .icon-shape .label{text-align:center;}#mermaid-svg-MpFMk43GrMKpGaAO .node.clickable{cursor:pointer;}#mermaid-svg-MpFMk43GrMKpGaAO .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-MpFMk43GrMKpGaAO .arrowheadPath{fill:#333333;}#mermaid-svg-MpFMk43GrMKpGaAO .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-MpFMk43GrMKpGaAO .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-MpFMk43GrMKpGaAO .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MpFMk43GrMKpGaAO .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-MpFMk43GrMKpGaAO .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MpFMk43GrMKpGaAO .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-MpFMk43GrMKpGaAO .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-MpFMk43GrMKpGaAO .cluster text{fill:#333;}#mermaid-svg-MpFMk43GrMKpGaAO .cluster span{color:#333;}#mermaid-svg-MpFMk43GrMKpGaAO div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-MpFMk43GrMKpGaAO .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-MpFMk43GrMKpGaAO rect.text{fill:none;stroke-width:0;}#mermaid-svg-MpFMk43GrMKpGaAO .icon-shape,#mermaid-svg-MpFMk43GrMKpGaAO .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MpFMk43GrMKpGaAO .icon-shape p,#mermaid-svg-MpFMk43GrMKpGaAO .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-MpFMk43GrMKpGaAO .icon-shape .label rect,#mermaid-svg-MpFMk43GrMKpGaAO .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MpFMk43GrMKpGaAO .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-MpFMk43GrMKpGaAO .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-MpFMk43GrMKpGaAO :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 拒绝
通过
通过
异常
业务事件
Schema 校验
权限预检
人工处理
规则执行
知识检索
Agent 计划
Skill Gateway
结果验证
业务写入
审计与恢复

确定性规则放在模型之前,减少状态数量。Agent 只负责非结构化理解与动作选择,Skill Gateway 负责参数、权限、超时和幂等。

3. Python 契约校验

python 复制代码
from dataclasses import dataclass


@dataclass(frozen=True)
class Contract:
    scene_id: str
    owner: str
    sample_count: int
    output_schema: str
    read_permissions: tuple[str, ...]
    write_permissions: tuple[str, ...]
    forbidden_actions: tuple[str, ...]
    human_gates: tuple[str, ...]
    acceptance_metrics: tuple[str, ...]
    recovery_checkpoint: str


def validate_contract(contract: Contract) -> list[str]:
    errors: list[str] = []

    required_text = {
        "scene_id": contract.scene_id,
        "owner": contract.owner,
        "output_schema": contract.output_schema,
        "recovery_checkpoint": contract.recovery_checkpoint,
    }
    for field, value in required_text.items():
        if not value.strip():
            errors.append(f"{field} is required")

    if contract.sample_count < 3:
        errors.append("at least 3 sanitized samples are required")
    if not contract.write_permissions:
        errors.append("write permission scope is required")
    if not contract.forbidden_actions:
        errors.append("forbidden action list is required")
    if not contract.human_gates:
        errors.append("human takeover conditions are required")
    if not contract.acceptance_metrics:
        errors.append("acceptance metrics are required")

    overlap = set(contract.write_permissions) & set(contract.forbidden_actions)
    if overlap:
        errors.append(f"permission conflict: {sorted(overlap)}")

    return errors

契约校验通过只代表材料齐全,不代表允许上线。风险评审和真实样例测试仍然是独立步骤。

4. 用数据库保存幂等动作

sql 复制代码
CREATE TABLE agent_action (
    id INTEGER PRIMARY KEY,
    request_id TEXT NOT NULL,
    action_name TEXT NOT NULL,
    target_id TEXT NOT NULL,
    idempotency_key TEXT NOT NULL UNIQUE,
    input_hash TEXT NOT NULL,
    status TEXT NOT NULL,
    external_request_id TEXT,
    result_json TEXT,
    updated_at TEXT NOT NULL
);

幂等键应由请求、动作和目标共同生成。同一个动作发生超时时,先通过外部请求 ID 查询真实结果,再决定是否重试。

5. 状态机必须可恢复

text 复制代码
RECEIVED -> VALIDATED -> PLANNED -> EXECUTING -> VERIFYING -> SUCCEEDED
                  |          |           |             |
                  +--------> HUMAN_REQUIRED <----------+
                                 |
                                 +-> RESUMING -> EXECUTING
                                 +-> CANCELLED

状态写入持久化存储后再执行外部动作。进程重启时读取当前状态、外部请求 ID 和幂等键,不能依赖内存变量判断是否继续。

6. 验收测试清单

场景 预期结果
输入缺字段 Schema 校验拒绝,不调用模型
权限不足 策略层阻断,不进入工具执行
相同请求重复到达 唯一幂等键阻止第二次写入
外部接口超时但实际成功 查询外部状态,不重复调用
回调乱序 暂存事件,等待合法状态
进程崩溃 从持久化检查点恢复
人工接管 自动 Worker 暂停同对象写权限
Skill 或知识版本升级 旧结果仍能按原版本追溯

需求阶段把这些失败路径写清楚,可以减少上线后才增加临时状态和补丁的情况。

本文由天远大数据根据企业 Agent 需求评估与工程实践整理。

相关推荐
回眸&啤酒鸭4 天前
【回眸】Minicart 电商购物车核心功能落地指南
人工智能
一隅论数智4 天前
给AI一张“业务概念地图“:本体如何从哲学走向企业智能
大数据·人工智能·经验分享·笔记·学习·学习方法·政务
默_笙4 天前
🍙 给每个请求过安检:FastAPI 是怎么把校验写进类型注解的
python
AI的探索之旅4 天前
97 个 OpenCV 实例(三十):双目立体,从标定到点云
人工智能·opencv·计算机视觉
AlbertZein4 天前
Step-5-Preview 上手实测:3D 游戏、金融分析、网页设计一次跑完
人工智能·aigc
LaughingZhu4 天前
Product Hunt 每日热榜 | 2026-09-19
人工智能·深度学习·神经网络·搜索引擎·百度
qq_426003964 天前
启动playwright录制codegen生成自动化测试脚本
python·自动化
虎头金猫4 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
美狐美颜SDK开放平台4 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk