ASCF Agent 详细设计方案
1. 概述
ascf-agent 是运行在 HarmonyOS 设备上的端侧 AI Agent,基于 ASCF (Atomic Service Cross Framework) 开发。它集成了 LLM 对话、Skill 加载、工具调用和 FlexView 卡片渲染能力。
1.1 设计目标
- 端侧 AI 助手:在 HarmonyOS 设备上运行完整的 AI Agent
- LLM 客户端:支持兼容 OpenAI API 的 LLM 服务
- Skill 系统:可扩展的 Skill 加载与执行框架
- 工具调用:支持 Function Calling 和 MCP Server 工具
- 卡片渲染:通过 FlexView 卡片引擎实现富 UI 交互
1.2 项目结构
ascf-agent/
├── entry/ → HarmonyOS 入口 App
│ ├── src/main/ets/
│ │ ├── entryability/EntryAbility.ets
│ │ └── pages/Index.ets → 主页面
│ └── src/main/resources/
│ └── rawfile/react/ → JS Bundle (FlexUI + React)
├── agent-runtime/ → Agent 运行时库
│ └── src/main/ets/
│ ├── AgentRuntime.ets → 公开外观类
│ ├── AgentRuntimeConfig.ets → 配置类型
│ ├── core/
│ │ ├── AgentLoop.ets → Agent 主循环
│ │ └── AgentTypes.ets → 类型定义
│ ├── llm/LlmClient.ets → LLM API 客户端
│ ├── tools/
│ │ ├── ToolRegistry.ets → 工具注册中心
│ │ ├── ToolExecutor.ets → 工具执行器
│ │ └── BuiltinTools.ets → 内置工具
│ ├── cards/
│ │ ├── CardRegistry.ets → 卡片注册中心
│ │ └── CardRenderer.ets → 卡片渲染器
│ ├── mcp/
│ │ ├── McpConfigLoader.ets → MCP 配置加载
│ │ └── McpTypes.ets → MCP 类型
│ ├── ui/ → UI 组件
│ │ ├── AgentChatView.ets → 对话视图
│ │ ├── ChatMessageList.ets → 消息列表
│ │ ├── ChatInputBar.ets → 输入栏
│ │ ├── MessageBubble.ets → 消息气泡
│ │ ├── MarkdownRenderer.ets → Markdown 渲染
│ │ ├── FlexCardView.ets → FlexView 卡片
│ │ ├── ChainOfThought.ets → 思考链展示
│ │ ├── TypingDots.ets → 打字动画
│ │ └── UIMessageTypes.ets → UI 数据类型
│ ├── utils/Logger.ets → 日志工具
│ └── Index.ets → 模块入口
├── AppScope/ → 应用配置资源
├── build-profile.json5 → 构建配置
└── scripts/ → 构建脚本
1.3 构建配置
ascf-agent 包含两个 HarmonyOS 模块:
// build-profile.json5
{
modules: [
{ name: "entry", srcPath: "./entry" },
{ name: "agent_runtime", srcPath: "./agent-runtime" }
]
}
2. 架构设计
┌──────────────────────────────────────────────────────┐
│ UI Layer (ArkUI) │
│ AgentChatView / ChatMessageList / MarkdownRenderer │
├──────────────────────────────────────────────────────┤
│ AgentRuntime (外观) │
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────┐ │
│ │ LlmClient │ │ AgentLoop │ │CardRenderer │ │
│ └──────┬──────┘ └──────┬───────┘ └──────┬──────┘ │
│ │ │ │ │
│ ┌──────┴─────────────────┴──────────────────┴──────┐ │
│ │ Tool & Card Registry │ │
│ │ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ ToolRegistry │ │ CardRegistry │ │ │
│ │ │ ToolExecutor │ │ (FlexView) │ │ │
│ │ └──────────────┘ └──────────────┘ │ │
│ └────────────────────────────────────────────────────┘ │
├──────────────────────────────────────────────────────┤
│ MCP (Model Context Protocol) │
│ McpConfigLoader → 加载 mcp.json → 注册 Tool + Card │
├──────────────────────────────────────────────────────┤
│ External Services │
│ LLM API (OpenAI Compatible) / MCP Servers │
└──────────────────────────────────────────────────────┘
3. 核心模块
3.1 AgentRuntime(外观类)
AgentRuntime 是 agent-runtime 库的公开入口,封装了所有内部模块。应用层只需实例化一个 AgentRuntime 即可使用全部功能。
class AgentRuntime {
constructor(config: AgentRuntimeConfig)
setContext(context: Context): void
initialize(): Promise<void>
run(userMessage: string, history: AgentMessage[], callbacks: AgentRunCallbacks): Promise<void>
cancel(): void
handleCardEvent(event: string): string
getRegisteredCards(): CardRegistryEntry[]
destroy(): void
}
配置项 (AgentRuntimeConfig):
| 配置 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| baseUrl | string? | - | LLM API 地址 |
| apiKey | string? | - | API Key |
| model | string? | deepseek-chat |
模型名称 |
| maxIterations | number? | 15 | 最大 Agent 循环次数 |
| mcpConfigPaths | string[]? | [] | MCP 配置文件路径 |
3.2 LlmClient(LLM 客户端)
通用的 LLM API 客户端,支持任何兼容 OpenAI Chat Completions API 的服务。
LlmClient
├── config: LlmClientConfig (baseUrl, apiKey)
├── chat(messages, tools?, systemPrompt?, model?)
│ └── 支持 Streaming (SSE) 响应
├── cancel() → 取消当前请求
└── 支持的模型: deepseek-chat, GPT-4, Claude 等
3.3 AgentLoop(Agent 主循环)
Agent 核心循环实现了标准的 LLM Agent 工作流:
用户消息
│
↓
[构建 messages + systemPrompt + tools]
│
↓
[调用 LLM] ←─────────────────┐
│ │
├── text_delta → 流式输出文字 │
├── reasoning → 展示思考过程 │
└── tool_calls → 执行工具 │
│ │
↓ │
[ToolExecutor.execute()] │
│ │
↓ │
[结果追加到 messages] ──────┘
│
↓ (无更多 tool_calls)
[返回最终文本 + 卡片]
AgentPhase 状态:
| Phase | 说明 |
|---|---|
| THINKING | 正在思考/输出文本 |
| TOOL_CALLING | 检测到工具调用意图 |
| TOOL_EXECUTING | 正在执行工具 |
| IDLE | 完成当前轮次 |
3.4 Tool System(工具系统)
ToolRegistry(工具注册中心)
ToolRegistry
├── register(tool) → 注册工具
├── getLLMToolDefinitions() → 获取 LLM Function Calling 格式的工具定义
└── execute(name, args) → 执行工具
ToolExecutor(工具执行器)
ToolExecutor
├── execute(toolCalls) → 批量执行工具调用
└── 返回 ToolResult[]
BuiltinTools(内置工具)
系统预注册的基础工具,如:
- 日期/时间查询
- 设备信息获取
- 基础计算
3.5 MCP Integration(MCP 集成)
通过 Model Context Protocol (MCP) 加载外部工具和卡片:
McpConfigLoader.loadConfig(mcpJsonPath, toolRegistry, cardRegistry, context)
│
├── 解析 mcp.json
├── 注册 Tool (ToolRegistry.register)
└── 注册 Card (CardRegistry.register)
3.6 Card System(卡片系统)
FlexView 卡片引擎的集成层:
CardRegistry
├── register(entry) → 注册卡片模板
└── getAll() → 获取所有卡片
CardRenderer
├── resolve(toolOutput) → 根据工具输出匹配卡片
└── 返回 CardRenderData → UI 层展示
3.7 UI 组件
| 组件 | 说明 |
|---|---|
| AgentChatView | 对话主界面,组合所有子组件 |
| ChatMessageList | 消息列表,支持虚拟滚动 |
| ChatInputBar | 输入栏,支持文本和语音 |
| MessageBubble | 消息气泡,区分用户/助手样式 |
| MarkdownRenderer | Markdown 渲染,支持代码高亮 |
| FlexCardView | FlexView 卡片渲染容器 |
| ChainOfThought | 思考链/推理过程展示 |
| TypingDots | 打字动画指示器 |
4. 数据流
4.1 对话流程
1. 用户输入 (ChatInputBar)
│
2. AgentRuntime.run(userMessage, history, callbacks)
│
3. AgentLoop 启动循环
│ ├── onTextDelta → UI 流式显示文字
│ ├── onReasoningDelta → ChainOfThought 展示
│ ├── onToolCallStart → 显示工具调用状态
│ ├── onToolCallEnd → 工具结果 + 可能的卡片展示
│ └── onCardReady → FlexCardView 渲染卡片
│
4. onComplete(finalMessage) → 消息历史更新
4.2 卡片交互流程
1. 工具返回数据 → CardRenderer.resolve()
│
2. 匹配到 CardRegistry 中的模板
│
3. FlexCardView 渲染 FlexView 卡片
│
4. 用户与卡片交互 (点击按钮等)
│
5. AgentRuntime.handleCardEvent(event)
│ └── 将事件格式化为用户消息文本
│
6. 重新进入 AgentLoop,上下文包含卡片交互信息
5. 构建与部署
5.1 构建命令
# 完整开发周期: 构建 HAP → 安装 → 启动
./build.sh dev-agent
# 仅构建 HAP
./build.sh build-agent
# 清理 + 构建
./build.sh clean-build
# 清理
./build.sh clean
# 查看日志
./build.sh logs
# 状态检查
./build.sh status
5.2 模块依赖
entry → agent-runtime (HarmonyOS 模块依赖)
agent-runtime → 无外部依赖 (纯 ArkTS/TypeScript)
6. 设计决策
6.1 为什么分离 entry 和 agent-runtime?
- 复用性:agent-runtime 可作为独立库被其他 HarmonyOS 应用集成
- 关注点分离:entry 负责应用配置和启动,agent-runtime 负责 AI Agent 逻辑
- 独立测试:agent-runtime 可独立进行单元测试
6.2 为什么用 AgentLoop 而非直接调用 LLM?
- 多轮推理:Agent 可能需要多次工具调用来完成一个任务
- 工具编排:AgentLoop 管理工具调用的序列化和上下文传递
- 可取消性:用户可随时中断 Agent 执行
6.3 为什么选择 MCP 协议?
- 标准化:MCP 是 Model Context Protocol 的行业标准,工具和卡片定义统一
- 可扩展:通过 mcp.json 文件动态加载工具,无需修改代码
- 生态兼容:与 Claude、GPT 等主流 Agent 生态的工具定义兼容
6.4 为什么支持 FlexView 卡片?
- 富交互:纯文本对话不够,卡片可以提供按钮、表单、图表等交互
- ASC Framework 原生:FlexView 是 ASCF 生态的轻量卡片引擎
- 工具结果可视化:将工具返回的结构化数据渲染为可视卡片