Skip to content

Tool-driven 交互式 UI 协议

Tool-driven 交互式 UI 协议

落地说明:本协议的 wire 层走 AG-UI 事件,前端由 assistant-ui 的 generative UI 渲染(见 ../03_architecture/05_tech_stack_decision.md);下文的 InteractionToolCall / InteractionToolResult 是与传输无关的业务 schema。

背景

AgentSurvey 的前端不应该只是聊天输入框。AI Agent 在访谈过程中应能根据研究目标自主决定是否调用交互组件,例如:

  • 单选;
  • 多选;
  • Likert;
  • NPS;
  • 排序;
  • 矩阵题;
  • 概念卡片;
  • 模态表单;
  • consent;
  • 文件上传;
  • 图片/原型反馈。

这类能力可以抽象成:

Agent tool call -> Interaction schema -> Frontend component -> User result -> Agent continuation

核心设计原则

  1. Agent 只声明“需要什么交互”,不关心 React 组件实现。
  2. 前端只根据 schema 渲染组件,不解析 prompt 意图。
  3. 用户交互结果必须以结构化 tool result 回传。
  4. 所有 tool call 和 result 都要进入 transcript/event log。
  5. 每次交互都要有 research_intent,方便后续解释。
  6. UI schema 需要版本化。

Interaction Tool Call

export type InteractionToolCall = {
tool: "render_interaction";
interaction_id: string;
schema_version: "2026-06-01";
type: InteractionType;
title: string;
description?: string;
instruction?: string;
required?: boolean;
allow_skip?: boolean;
research_intent: string;
output_schema: JsonSchema;
evidence_policy?: EvidencePolicy;
display?: InteractionDisplay;
validation?: InteractionValidation;
metadata?: Record<string, unknown>;
};

Interaction Types

export type InteractionType =
| "single_choice"
| "multiple_choice"
| "likert"
| "nps"
| "rating"
| "ranking"
| "matrix"
| "text_input"
| "modal_form"
| "concept_card"
| "comparison"
| "consent"
| "file_upload"
| "image_annotation"
| "task_confirmation";

通用字段

export type ChoiceOption = {
id: string;
label: string;
description?: string;
value?: string | number | boolean;
exclusive?: boolean;
metadata?: Record<string, unknown>;
};
export type InteractionDisplay = {
mode?: "inline_card" | "modal" | "side_panel" | "full_screen";
compact?: boolean;
show_progress?: boolean;
confirm_before_submit?: boolean;
};
export type EvidencePolicy =
| "cite_selection"
| "cite_free_text"
| "cite_followup_turn"
| "no_citation_needed";

示例:单选

{
"tool": "render_interaction",
"interaction_id": "int_primary_pain_001",
"schema_version": "2026-06-01",
"type": "single_choice",
"title": "你当前最主要的痛点是什么?",
"description": "请选择最接近的一项,后面我会继续追问具体例子。",
"required": true,
"allow_skip": true,
"research_intent": "identify_primary_pain_point",
"options": [
{"id": "setup_complexity", "label": "配置复杂"},
{"id": "low_response_quality", "label": "回答质量不稳定"},
{"id": "manual_analysis", "label": "人工整理成本高"},
{"id": "tool_fragmentation", "label": "工具链分散"},
{"id": "other", "label": "其他"}
],
"output_schema": {
"type": "object",
"properties": {
"selected_option_id": {"type": "string"},
"selected_label": {"type": "string"}
},
"required": ["selected_option_id"]
},
"evidence_policy": "cite_selection",
"display": {"mode": "inline_card"}
}

示例:多选

{
"tool": "render_interaction",
"interaction_id": "int_tool_needs_001",
"schema_version": "2026-06-01",
"type": "multiple_choice",
"title": "这个平台你最需要哪些能力?",
"description": "最多选择 3 项。",
"research_intent": "prioritize_platform_capabilities",
"options": [
{"id": "multi_project", "label": "多项目管理"},
{"id": "rag", "label": "知识库/RAG"},
{"id": "interactive_ui", "label": "交互式问卷组件"},
{"id": "evidence", "label": "证据链输出"},
{"id": "custom_tools", "label": "自定义工具"}
],
"validation": {"min_items": 1, "max_items": 3},
"output_schema": {
"type": "object",
"properties": {
"selected_option_ids": {
"type": "array",
"items": {"type": "string"}
}
},
"required": ["selected_option_ids"]
}
}

示例:Likert

{
"tool": "render_interaction",
"interaction_id": "int_value_rating_001",
"schema_version": "2026-06-01",
"type": "likert",
"title": "如果这个平台能自动产出带证据链的结构化访谈结果,你觉得价值有多大?",
"research_intent": "measure_perceived_value",
"scale": {
"min": 1,
"max": 5,
"min_label": "完全没价值",
"max_label": "非常有价值"
},
"output_schema": {
"type": "object",
"properties": {
"score": {"type": "integer", "minimum": 1, "maximum": 5}
},
"required": ["score"]
}
}

示例:排序

{
"tool": "render_interaction",
"interaction_id": "int_feature_ranking_001",
"schema_version": "2026-06-01",
"type": "ranking",
"title": "请按重要性排序这些能力",
"research_intent": "rank_feature_importance",
"options": [
{"id": "agent_harness", "label": "Agent Harness"},
{"id": "ui_tools", "label": "交互式 UI 工具"},
{"id": "kb", "label": "知识库"},
{"id": "schema_extraction", "label": "结构化抽取"},
{"id": "exports", "label": "导出/集成"}
],
"output_schema": {
"type": "object",
"properties": {
"ranked_option_ids": {
"type": "array",
"items": {"type": "string"}
}
},
"required": ["ranked_option_ids"]
}
}

Tool Result

export type InteractionToolResult = {
interaction_id: string;
type: InteractionType;
status: "submitted" | "skipped" | "cancelled" | "expired";
value: unknown;
submitted_at: string;
client_context?: {
duration_ms?: number;
changed_count?: number;
device?: "desktop" | "mobile" | "tablet";
};
};

示例:

{
"interaction_id": "int_primary_pain_001",
"type": "single_choice",
"status": "submitted",
"value": {
"selected_option_id": "manual_analysis",
"selected_label": "人工整理成本高"
},
"submitted_at": "2026-06-22T10:30:00Z",
"client_context": {
"duration_ms": 5400,
"device": "desktop"
}
}

前端渲染映射

interaction type推荐组件
single_choiceRadioCardGroup
multiple_choiceCheckboxCardGroup
likertLikertScale
npsNpsScale
ratingStarRating / NumericRating
rankingDragSortableList
matrixMatrixQuestionTable
text_inputTextAreaCard
modal_formModalForm
concept_cardStimulusCard
comparisonComparisonCards
consentConsentPanel
file_uploadUploadDropzone
image_annotationImageFeedbackCanvas
task_confirmationConfirmationCard

Agent 使用策略

Agent 不应滥用交互组件。建议规则:

  1. 当需要可比较、可统计的数据时调用组件。
  2. 当用户开放回答已经足够清楚时,不必再弹组件。
  3. 一个 screen 最多展示一个主交互。
  4. 组件之后通常要有自然语言 follow-up。
  5. 对敏感问题应允许跳过。
  6. 对研究关键字段,可先问开放题,再用组件确认。

数据记录

每次 interaction 都应写入:

  • tool_calls
  • interaction_events
  • transcript_turns
  • extraction_evidence
  • session_state

这样才能后续重放、审计和分析。