课程首页 › Module 8 · 生产部署:可观测 / Foundry / UX › L21

L21 Agent UX 设计:让 Agent "用得爽"的产品设计原则

课程目标:理解 Agent 作为产品形态的 UX 设计原则,掌握透明度、流式响应、错误恢复、HITL 协作、信任建立五大设计模式。


一、Agent 不只是技术问题,更是产品问题#

你的 Agent 后端跑了:

用户:订明天上午的会议室
Agent:好的,我帮你预订
(5 秒后)已预订明天上午 9 点的会议室 A

技术上完美。但用户实际体验:

用户:订明天上午的会议室
(屏幕静止)
(用户不知道 Agent 在做什么)
(10 秒后)已预订明天上午 9 点的会议室 A
(用户:等等,我说的是 10 点啊)
(再次静止……)

技术 OK ≠ 产品 OK。Agent 的 UX 设计决定了用户愿不愿意用。

这一课我们学五件事:

  1. 透明度:让用户知道 Agent 在做什么

  2. 流式响应:让等待显得更短

  3. 错误恢复:怎么优雅失败

  4. HITL UX:人工审批的体验设计

  5. 信任建立:让用户相信 Agent


二、用一个比喻:Agent UX = 餐厅服务#

把 Agent 比作餐厅服务:

餐厅服务Agent UX
客人进门,服务员说"欢迎光临"Agent 主动打招呼、确认需求
服务员说"我去厨房看看"Agent 显示"正在调用工具 X..."
厨师现场做菜,客人能看到流式响应(实时打字效果)
"今天的鱼不太新鲜,要不要换牛排?"Agent 主动澄清、提供替代方案
上错菜了,服务员马上道歉换菜错误恢复(识别 + 道歉 + 重做)
大额消费需要经理确认HITL(敏感操作人工审批)
菜单明确、食材来源可查透明度(来源标注、能力边界说明)

好餐厅 vs 差餐厅——服务生说话的语气、节奏、专业度,决定复购率。

Agent 也一样。


三、设计原则 1:透明度(Transparency)#

核心思想#

用户应该知道 Agent 在做什么、为什么做、下一步要做什么。

反例:黑盒 Agent#

用户:帮我处理这个 bug
Agent:(5 秒后)已经修复了。
用户:怎么修的?会不会影响其他地方?
Agent:(沉默)

正例:透明 Agent#

用户:帮我处理这个 bug
Agent:好的,我先看一下代码...

[显示进度]
🔍 正在分析 file.py
✓ 发现 bug 在第 42 行:变量未初始化
🔧 正在应用修复方案
✓ 修复完成,已写测试用例验证

修改内容:
- file.py 第 42-45 行:初始化变量
- test_file.py 新增测试用例

需要我提交 PR 吗?

实现:结构化进度展示#

from enum import Enum
from dataclasses import dataclass

class AgentStepType(Enum):
    THINKING = "thinking"
    TOOL_CALL = "tool_call"
    TOOL_RESULT = "tool_result"
    FINAL_ANSWER = "final_answer"

@dataclass
class AgentStep:
    type: AgentStepType
    title: str           # 用户看到的标题
    detail: str = ""     # 详细信息(可选)
    icon: str = ""       # emoji 图标
    metadata: dict = None

# 在 Agent 中发出进度事件
def emit_progress(step_type: AgentStepType, title: str, 
                  detail: str = "", icon: str = ""):
    """向用户推送进度"""
    step = AgentStep(type=step_type, title=title, detail=detail, icon=icon)
    # 通过 SSE / WebSocket 推送到前端
    yield f"event: progress\ndata: {json.dumps(asdict(step))}\n\n"

前端消费示例(React)#

function AgentProgress({ steps }) {
  return (
    <div className="agent-progress">
      {steps.map((step, i) => (
        <div key={i} className={`step step-${step.type}`}>
          <span className="icon">{step.icon}</span>
          <div>
            <div className="title">{step.title}</div>
            {step.detail && <div className="detail">{step.detail}</div>}
          </div>
        </div>
      ))}
    </div>
  );
}

关键设计决策#

设计选择推荐原因
是否显示每次思考?折叠/可展开太啰嗦用户烦,太简洁用户不知道
是否显示工具参数?用户触发时展开默认隐藏,感兴趣可看
错误是否详细说明?是用户需要知道为什么失败
成功的步骤是否显示?简洁版✓ 而不是详细日志

四、设计原则 2:流式响应(Streaming)#

核心思想#

让用户尽早看到结果,而不是等所有都完成。

反例:阻塞响应#

用户:写一篇关于 AI Agent 的文章
Agent:(30 秒后)已写完,5000 字...
用户:(不知道什么时候完成,也不知道质量如何)

正例:流式响应#

用户:写一篇关于 AI Agent 的文章
Agent:(1 秒后开始打字)
AI Agent 是一种...
(持续打字,用户看到进度)
(30 秒内完成)

实现:Server-Sent Events(SSE)#

from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from langchain_openai import ChatOpenAI
import asyncio

app = FastAPI()
llm = ChatOpenAI(model="gpt-4o-mini", streaming=True)

async def stream_agent_response(user_message: str):
    """流式生成 Agent 响应"""
    
    # 1. 发送"开始"事件
    yield f"event: start\ndata: {{\"message\": \"开始处理\"}}\n\n"
    
    # 2. 发送进度事件
    yield f"event: step\ndata: {{\"title\": \"正在分析需求\", \"icon\": \"🔍\"}}\n\n"
    await asyncio.sleep(0.5)
    
    # 3. 流式 LLM 输出
    accumulated_response = ""
    async for chunk in llm.astream([{"role": "user", "content": user_message}]):
        if chunk.content:
            accumulated_response += chunk.content
            yield f"event: token\ndata: {{\"text\": \"{chunk.content}\"}}\n\n"
    
    # 4. 发送"完成"事件
    yield f"event: done\ndata: {{\"total_length\": {len(accumulated_response)}}}\n\n"

@app.post("/agent/stream")
async def stream_agent(request: AgentRequest):
    return StreamingResponse(
        stream_agent_response(request.message),
        media_type="text/event-stream"
    )

前端消费(React + EventSource)#

function AgentStreamView() {
  const [content, setContent] = useState("");
  const [steps, setSteps] = useState([]);
  
  const startStream = async (message) => {
    const response = await fetch("/agent/stream", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ message })
    });
    
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    let buffer = "";
    
    while (true) {
      const { done, value } = await reader.read();
      if (done) break;
      
      buffer += decoder.decode(value, { stream: true });
      const events = buffer.split("\n\n");
      buffer = events.pop();
      
      for (const event of events) {
        const [typeLine, dataLine] = event.split("\n");
        const type = typeLine.replace("event: ", "");
        const data = JSON.parse(dataLine.replace("data: ", ""));
        
        if (type === "token") {
          setContent(prev => prev + data.text);
        } else if (type === "step") {
          setSteps(prev => [...prev, data]);
        }
      }
    }
  };
  
  return (
    <div>
      <div className="steps">
        {steps.map((step, i) => (
          <div key={i}>{step.icon} {step.title}</div>
        ))}
      </div>
      <div className="content">{content}</div>
    </div>
  );
}

Token 级 vs 句子级流式#

粒度优点缺点
Token 级(一个字一个字)最流畅网络开销大
句子级(一句话一句话)平衡流畅和开销不够流畅
段落级(一段一段)网络开销小等待感强

推荐:Token 级 + 客户端缓冲(每 50ms 渲染一次,平衡流畅和性能)。


五、设计原则 3:错误恢复(Graceful Failure)#

核心思想#

Agent 一定会失败——LLM 调用失败、工具失败、用户输入歧义、网络问题。

关键是:失败时怎么对待用户。

反例:技术式失败#

用户:帮我订会议室
Agent:Error: API call failed: timeout (30s)
(技术错误直接暴露给用户)

正例:优雅失败#

用户:帮我订会议室
Agent:抱歉,会议室预订系统暂时连不上 😔
我先帮你记下需求:
- 时间:明天上午
- 人数:8 人
- 偏好:靠近窗户

等系统恢复后我会自动帮你订。或者你可以稍后再问我。
需要我设置一个提醒吗?

错误处理模式#

from enum import Enum

class ErrorType(Enum):
    NETWORK_ERROR = "network"          # 网络问题
    LLM_RATE_LIMIT = "rate_limit"      # LLM 限流
    TOOL_NOT_FOUND = "tool_not_found"  # 工具不存在
    AMBIGUOUS_INPUT = "ambiguous"      # 输入歧义
    PERMISSION_DENIED = "permission"   # 权限不足
    UNKNOWN = "unknown"

ERROR_MESSAGES = {
    ErrorType.NETWORK_ERROR: {
        "title": "网络连接问题",
        "message": "我暂时连不上 {service},稍后再试吧。",
        "action": "retry",
        "icon": "🌐"
    },
    ErrorType.LLM_RATE_LIMIT: {
        "title": "服务繁忙",
        "message": "请求太多了,请稍等 30 秒再试。",
        "action": "wait_retry",
        "icon": "⏰"
    },
    ErrorType.AMBIGUOUS_INPUT: {
        "title": "信息不完整",
        "message": "我需要更多信息:{clarification_questions}",
        "action": "ask_clarification",
        "icon": "❓"
    },
    ErrorType.PERMISSION_DENIED: {
        "title": "权限不足",
        "message": "这个操作需要 {required_role} 权限。",
        "action": "escalate",
        "icon": "🔒"
    }
}

def user_facing_error(error_type: ErrorType, **context) -> dict:
    """生成面向用户的错误信息"""
    template = ERROR_MESSAGES.get(error_type, ERROR_MESSAGES[ErrorType.UNKNOWN])
    return {
        "title": template["title"],
        "message": template["message"].format(**context),
        "action": template["action"],
        "icon": template["icon"]
    }

# 在 Agent 中使用
try:
    result = tool.invoke(args)
except NetworkError:
    return user_facing_error(ErrorType.NETWORK_ERROR, service="会议室系统")
except AmbiguousRequestError as e:
    return user_facing_error(
        ErrorType.AMBIGUOUS_INPUT,
        clarification_questions=e.questions
    )

主动澄清(Clarification)#

关键原则:用户输入歧义时,主动追问而不是猜。

CLARIFICATION_PROMPT = """用户输入:{user_input}

评估这个输入是否需要澄清:
- 信息不完整(缺时间、数量、对象)→ 需要澄清
- 多种合理理解 → 需要澄清
- 完全清晰 → 不需要澄清

输出格式:
NEEDS_CLARIFICATION: yes/no
QUESTIONS: <列出需要问的问题,每行一个>
REASON: <为什么需要澄清>
"""

def should_clarify(user_input: str) -> tuple[bool, list[str]]:
    """判断是否需要主动澄清"""
    response = llm.invoke(CLARIFICATION_PROMPT.format(user_input=user_input))
    
    if "NEEDS_CLARIFICATION: yes" in response.content:
        questions = re.findall(r"^\d+\.\s*(.+)$", response.content, re.MULTILINE)
        return True, questions
    
    return False, []

# 用法示例
needs_clarify, questions = should_clarify("帮我订个会议室")
# needs_clarify=True
# questions=[
#   "什么时间?",
#   "多少人参加?",
#   "有什么特殊要求(投影、白板等)?"
# ]

六、设计原则 4:HITL UX 设计#

核心思想#

人工审批应该是"友好的协作",而不是"麻烦的阻碍"。

反例:粗暴的中断#

Agent:我要执行 delete_file(/data/important.json)
(突然弹出全屏对话框,必须立刻决定)
用户:什么?!等等,我看看...
(用户被吓到,不敢点了)

正例:渐进式审批#

Agent:我想要删除 /data/important.json

[预览文件内容]
[显示删除影响]
[提供替代选项]

请选择:
[确认删除] [先备份] [取消] [看更多]

实现:渐进式 HITL#

from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.checkpoint.memory import MemorySaver

def agent_with_hitl(state: MessagesState):
    last_msg = state["messages"][-1]
    
    if last_msg.tool_calls:
        tool_call = last_msg.tool_calls[0]
        
        if is_sensitive(tool_call["name"]):
            # 不要直接调用,发送"等待审批"消息
            preview = generate_preview(tool_call)
            
            return {
                "messages": [{
                    "role": "assistant",
                    "content": f"""⚠️ 我想执行 **{tool_call['name']}**,需要你确认。

**预览**:
{preview}

**影响范围**:{analyze_impact(tool_call)}

**选项**:
- 确认执行
- 修改参数
- 取消""",
                    "tool_calls": [tool_call]  # 保留 tool_call 等用户确认
                }],
                "__awaiting_approval__": True
            }
    
    return {"messages": [llm.invoke(state["messages"])]}

def preview_file_deletion(path: str) -> str:
    """生成文件删除的预览"""
    if os.path.exists(path):
        size = os.path.getsize(path)
        last_modified = datetime.fromtimestamp(os.path.getmtime(path))
        with open(path, "r") as f:
            content_preview = f.read()[:500]
        return f"""
文件:{path}
大小:{size} 字节
最后修改:{last_modified}
内容预览:

{content_preview}

"""
    return f"⚠️ 文件 {path} 不存在"

def analyze_impact(tool_call) -> str:
    """分析工具调用的影响"""
    if tool_call["name"] == "delete_file":
        path = tool_call["args"]["path"]
        # 检查是否有其他文件依赖
        dependents = find_dependents(path)
        if dependents:
            return f"⚠️ 以下文件可能依赖此文件:{dependents}"
        return "无明显依赖"

前端 UX(渐进式审批)#

function ApprovalCard({ toolCall, onApprove, onReject }) {
  return (
    <div className="approval-card">
      <div className="warning-header">
        ⚠️ Agent 请求执行敏感操作
      </div>
      
      <div className="preview">
        <h4>{toolCall.name}</h4>
        <pre>{JSON.stringify(toolCall.args, null, 2)}</pre>
      </div>
      
      <div className="impact">
        {toolCall.impact}
      </div>
      
      <div className="actions">
        <button className="primary" onClick={onApprove}>
          ✓ 确认执行
        </button>
        <button className="secondary" onClick={() => onApprove({...toolCall, modified: true})}>
          ✏️ 修改参数
        </button>
        <button className="tertiary" onClick={onReject}>
          ✗ 取消
        </button>
      </div>
      
      <div className="hint">
        💡 提示:你也可以让 Agent 完全自主处理
        <a href="/settings/permissions">权限设置</a>
      </div>
    </div>
  );
}

七、设计原则 5:建立信任#

信任的三大支柱#

   能力(Capability)
      /\
     /  \
    /    \
   /      \
  /  信任   \
 /__________\
能力    品行
      (Character)

用户信任 Agent 的两个维度:

信任建设模式 1:来源标注#

RESPONSE_WITH_SOURCES_PROMPT = """请回答用户问题,每个事实标注来源。

格式:
[事实描述] [来源: 文档名/工具名/数据库]

如果没有可靠来源,明确说"我不确定"。

用户问题:{question}
"""

# 示例输出:
# "公司有 3 个办公室 [来源: 内部wiki]"
# "Q3 营收增长 12% [来源: 财务系统]"
# "我不确定该数据的准确性 [来源: 无]"

信任建设模式 2:能力边界声明#

┌─────────────────────────────────────────┐
│ 我能帮你:                                │
│ ✓ 查询订单状态                            │
│ ✓ 查询物流                                │
│ ✓ 回答常见问题                            │
│                                          │
│ 我不能:                                  │
│ ✗ 修改订单(请联系人工)                   │
│ ✗ 退款(请联系人工)                      │
│ ✗ 给出投资建议                            │
│                                          │
│ 当我不确定时,我会诚实告诉你                │
└─────────────────────────────────────────┘

实现:在 Agent 欢迎语 + 每次出错时明确说明。

def welcome_message():
    return """👋 你好!我是订单助手。

我可以帮你:
• 查询订单状态和物流
• 解答常见问题

如果遇到我做不到的事,我会老实告诉你并建议下一步。

你想问什么?"""

def capability_disclaimer():
    return """⚠️ 注意:我只能查询订单状态,不能修改或退款。
如果需要这些操作,请联系人工客服。"""

信任建设模式 3:可逆操作#

class ReversibleAction:
    """可逆操作 - 给用户"后悔药" """
    
    def execute_with_undo(self, action: Callable, *args, **kwargs):
        """执行操作,保留撤销能力"""
        snapshot = self._create_snapshot()
        try:
            result = action(*args, **kwargs)
            self._undo_stack.append({
                "action": action,
                "args": args,
                "kwargs": kwargs,
                "snapshot": snapshot,
                "timestamp": time.time()
            })
            return result
        except Exception:
            self.restore_snapshot(snapshot)
            raise
    
    def undo_last(self):
        """撤销最近一次操作"""
        if self._undo_stack:
            last = self._undo_stack.pop()
            self.restore_snapshot(last["snapshot"])
            return f"已撤销 {last['action'].__name__}"

信任建设模式 4:错误时的诚实#

HONEST_FAILURE_PROMPT = """任务失败了,请诚实地告诉用户:

1. 发生了什么(不要隐瞒)
2. 为什么会失败(可能的原因)
3. 用户可以做什么(替代方案)

不要说"成功"或"已处理",除非真的成功。
不要说"系统问题"(太模糊),而要说具体原因。

任务:{task}
错误:{error}
"""

def honest_failure_message(task: str, error: Exception) -> str:
    """生成诚实的失败消息"""
    response = llm.invoke(HONEST_FAILURE_PROMPT.format(
        task=task, 
        error=str(error)
    ))
    return response.content

# 输出示例:
# "抱歉,我没能删除那个文件。原因是文件正在被另一个程序占用。
# 你可以:
# 1. 关闭占用程序后再让我试
# 2. 让我用 force 参数强制删除(但可能会丢失未保存的修改)
# 3. 你自己手动删除"

八、设计原则 6:对话连续性#

记忆与上下文#

class ConversationMemory:
    """对话记忆 - 让 Agent 记住之前的对话"""
    
    def __init__(self, max_recent: int = 20, max_summary_tokens: int = 500):
        self.recent_messages = []  # 最近的 N 条
        self.summary = ""          # 早期对话的摘要
    
    def add(self, message):
        self.recent_messages.append(message)
        
        # 超出长度时,触发摘要
        if len(self.recent_messages) > self.max_recent:
            self._compress()
    
    def _compress(self):
        """把早期消息压缩成摘要"""
        old_messages = self.recent_messages[:10]
        self.recent_messages = self.recent_messages[10:]
        
        new_summary = llm.invoke([
            {"role": "system", "content": "请总结以下对话的关键信息:"},
            *old_messages,
            {"role": "system", "content": f"之前的摘要:{self.summary}"}
        ]).content
        
        self.summary = new_summary
    
    def get_context(self) -> list:
        """获取送入 LLM 的完整上下文"""
        messages = []
        if self.summary:
            messages.append({
                "role": "system",
                "content": f"对话摘要:{self.summary}"
            })
        messages.extend(self.recent_messages)
        return messages

多轮对话的体验设计#

设计实现
显示历史对话保留完整的消息气泡
支持引用回复点击历史消息可引用
支持重新生成不满意可让 Agent 重新生成
支持编辑消息用户可以修改自己的输入让 Agent 重答
对话搜索长对话可搜索

九、设计原则 7:边界与诚实#

关键反例:幻觉式自信#

用户:2024 年奥运会男子 100 米冠军是谁?
Agent:是博尔特,成绩 9.58 秒。
(错误:博尔特是 2008、2012、2016 年冠军,不是 2024 年)
(Agent 自信地胡说)

正例:诚实的 Agent#

用户:2024 年奥运会男子 100 米冠军是谁?
Agent:我不太确定 2024 年奥运会的具体情况,因为我的知识截止到 [日期]。
让我查一下...

[调用搜索工具]
... 

查到了,是 [名字],成绩 [成绩]。来源 [URL]。

实现:知识截止与不确定性#

UNCERTAINTY_AWARE_PROMPT = """你是一个诚实的助手。

规则:
1. 不知道的事,明确说"我不确定"或"我的知识可能不准确"
2. 不要编造事实、数据、人名
3. 知识截止日期:{knowledge_cutoff}
4. 如果问题涉及截止日期之后的事件,建议用户查询最新信息
5. 如果不确定,先调用搜索工具再回答

用户问题:{question}
"""

KNOWLEDGE_CUTOFF = "2024 年 4 月"  # 根据模型调整

def uncertain_agent(question: str) -> str:
    """带不确定性意识的 Agent"""
    response = llm.invoke(UNCERTAINTY_AWARE_PROMPT.format(
        knowledge_cutoff=KNOWLEDGE_CUTOFF,
        question=question
    ))
    return response.content

十、和 L1-L9 的连接#

课程在 Agent UX 中的角色
L2 ReAct透明度设计的基础(每一步都是 UX 元素)
L5 LangGraph流式响应和状态管理
L6 多 Agent多 Agent 协调的 UX 设计
L10 Agentic RAG检索过程透明化
L13 安全HITL UX 设计
L19 生产部署监控数据反馈到 UX 改进

十一、动手时间:30 分钟 UX 设计实验#

实验 1:透明度设计(10 分钟)#

给你现有的 Agent 加进度展示,让用户看到"正在做什么"。

实验 2:流式响应(10 分钟)#

把现有的阻塞响应改成 SSE 流式,观察响应速度感的变化。

实验 3:错误恢复 UX(10 分钟)#

故意触发 3 种错误(网络失败、歧义输入、权限不足),让 Agent 用友好方式处理。

📋 UX 设计 checklist(点击展开)

透明度 checklist#

流式响应 checklist#

错误恢复 checklist#

HITL UX checklist#

信任建立 checklist#


十二、设计模式速查#

模式何时用关键设计
进度展示任何 Agent 调用步骤化、可折叠
流式响应长任务(>2 秒)Token 级流式、进度条
错误恢复任何失败路径友好消息 + 替代方案
渐进式 HITL敏感操作预览 + 影响 + 多选项
来源标注任何事实陈述内联引用 + 可追溯
能力边界首次使用 + 失败时明确什么能做/不能做
诚实失败任何错误不掩盖、不模糊
可逆操作写入操作撤销栈 + 快照
对话记忆多轮对话摘要 + 最近消息
主动澄清歧义输入列举可能问题

十三、小结#

知识点一句话回顾
透明度让用户知道 Agent 在做什么、为什么
流式响应尽早给反馈,不要等所有都完成
错误恢复友好消息 + 替代方案 + 不让用户卡住
HITL UX渐进式审批 + 预览影响 + 多选项
信任建立来源标注 + 能力边界 + 诚实失败 + 可逆操作
对话连续性摘要 + 最近消息 + 支持编辑重答
诚实边界不确定时明确说,不编造

十四、Read next#

🎉 恭喜你完成了所有 L9-L23 进阶与生产课程!

完整学习路径:

L0 → L1 → L2 → L3 → L4 → L5 → L6 → L7 → L8 → L9 → L10 (主课程 + 进阶 11 节)
         ↓
   L11 → L12 → L13 → L14 → L15 → L16 → L17 → L18 (协议与工程 8 节)
         ↓
   L19 → L20 → L21 → L22 → L23 (生产、安全与工作流 5 节)
         ↓
   L24 → L25 → L26 → L27 (高级专题:多模态/调试/防御/测试 4 节)

完整能力矩阵#

维度课程
概念L1-L2
实战L3-L5
架构L6, L7-L8
质量L8, L10, L27
安全L13, L22, L26
生产L19-L20
产品L21
工具选择L9
工作流工程L23
多模态L24
调试L25

接下来可以做什么#

  1. 找工作准备:复习 L1-L6,准备面试高频问题

  2. 做项目:用 L9-L27 的知识做一个生产级 Agent

  3. 读论文:ReWOO、Reflexion、Anthropic multi-agent 等

  4. HF 期末项目:完成 HF Agents Course 拿证书

  5. 持续跟进:MCP、多 Agent 协议、Agent 评估等领域还在快速演进

高级专题(可选)#

L24-L27 是上线后会用到的高级专题——多模态 / 调试 / 防御 / 测试:

主要参考:


十五、Sources#


💬 有疑问? 试试问我:"Agent 怎么让用户信任?"、"HITL 的最佳实践是什么?"、"流式响应怎么避免太碎片化?"——我会用代码或比喻为你解答。

🎓 学习完毕:你已具备 AI Agent 工程师的核心能力栈。继续保持关注——这个领域每周都有新进展。

自测 · 检验是否真的掌握了

1. 流式响应(Streaming)改善 Agent 体验的核心原理是什么?

流式响应不改变模型的实际生成速度,它改变的是用户的主观等待感:尽早看到第一个 token 后,等待就从「不知道在干嘛」变成「正在成型」。真正提速要靠更快的模型、压缩上下文或缓存。流式的完整内容仍然是最终答案,中间片段只是让等待可见,因此不能替代最终输出。

2. 渐进式 HITL(人工审批)的正确设计姿态是什么?

渐进式审批把审批变成友好协作:先展示操作内容预览和影响范围,再给出确认执行、修改参数、取消等多个选项,让用户有信息也有选择。突然弹全屏对话框会吓到用户,全都要审批则失去了自动化的意义,而事后通知已经来不及阻止伤害。审批应出现在不可逆动作发生之前。

3. 关于「用户信任 Agent 的两个维度」,下列说法正确的是哪一个?

课程把信任拆成能力与品行两个维度:能力是 Agent 能不能把事做好,行品是它是否诚实、可靠、说到做到。速度、成本、界面这些是体验指标,记忆与推理是技术能力,它们会影响信任但不等于信任本身。信任建设因此要靠来源标注、能力边界声明、诚实失败和可逆操作这些具体手段。