Dart Agent Core 实战教程:在 Flutter 应用中集成 AI Agent,给移动端加上智能对话能力
当你的 Flutter 应用需要 AI 能力时,常规做法是写一个后端服务(Python 或 Node.js),然后在移动端调用 API。但有了 Dart Agent Core,你可以在 Dart/Flutter 中直接运行完整的 AI Agent 循环——工具调用、多轮记忆、技能系统、子代理,全在客户端完成,不需要后端。
为什么在 Flutter 中直接运行 Agent?
大部分 AI Agent 框架都是 Python 或 Node.js 生态的,在移动端部署意味着:
- 需要额外搭建一个后端 Proxy 服务
- 网络延迟增加,离线场景完全不可用
- 状态管理复杂,会话上下文跨网络传输慢
Dart Agent Core(GitHub,MIT,31⭐)直接解决了这些问题。它实现了完整的 Agent 循环状态机——LLM 调用、工具执行、多轮对话、技能管理、子代理调度,全部在 Dart 中运行。支持 OpenAI、Gemini、Claude 等主流模型,覆盖 Android、iOS、Web、Windows、macOS、Linux 全部六平台,WebAssembly 兼容。
快速上手:一个天气 Agent
安装依赖后,创建一个带工具调用的天气查询 Agent 只需要几十行代码。
dependencies: dart_agent_core: ^2.0.4
import 'dart:io';
import 'package:dart_agent_core/dart_agent_core.dart';
String getWeather(String location) {
if (location.toLowerCase().contains('tokyo')) return 'Sunny, 25°C';
return 'Weather data not available for this location';
}
void main() async {
final apiKey = Platform.environment['OPENAI_API_KEY'] ?? '';
final client = OpenAIClient(apiKey: apiKey);
final modelConfig = ModelConfig(model: 'gpt-4o-mini');
final weatherTool = Tool(
name: 'get_weather',
description: 'Get the current weather for a city.',
executable: getWeather,
parameters: {
'type': 'object',
'properties': {
'location': {
'type': 'string',
'description': 'City name, e.g. Tokyo',
},
},
'required': ['location'],
},
);
final agent = StatefulAgent(
name: 'weather_agent',
client: client,
tools: [weatherTool],
modelConfig: modelConfig,
state: AgentState.empty(),
systemPrompts: ['You are a helpful assistant.'],
);
final responses = await agent.run([
UserMessage.text('What is the weather like in Tokyo right now?'),
]);
print((responses.last as ModelMessage).textOutput);
}
执行逻辑很清晰:Agent 收到用户消息 → LLM 决定调用 get_weather 工具 → Dart 函数执行 → 结果返回给 LLM → LLM 生成自然语言回复。整个过程在同一 Dart 进程中完成,零网络跳转。
在 Web 环境中运行
Dart Agent Core 的一大亮点是 WebAssembly 兼容。在 Web 平台上,Platform.environment 不可用,需要通过浏览器 localStorage 读取 API Key:
import 'package:web/web.dart' as web;
import 'package:dart_agent_core/dart_agent_core.dart';
void main() async {
final apiKey = web.window.localStorage.getItem('OPENAI_API_KEY') ?? '';
final client = OpenAIClient(apiKey: apiKey);
// 其余代码与 Quick Start 相同
}
Web 环境下使用
package:web(WASM 兼容),避免已废弃的dart:html。状态存储改用localStorage或内存存储,而非FileStateStorage。
多模型支持:一套 API,多个 Provider
不需要为每个模型写不同的接入逻辑。Dart Agent Core 统一了 LLMClient 接口:
// OpenAI Chat Completions final client = OpenAIClient( apiKey: Platform.environment['OPENAI_API_KEY'] ?? '', ); // OpenAI Responses API(状态化接口,自动传递 previous_response_id) final client = ResponsesClient( apiKey: Platform.environment['OPENAI_API_KEY'] ?? '', ); // Google Gemini final client = GeminiClient( apiKey: Platform.environment['GEMINI_API_KEY'] ?? '', ); // Claude(直接调用 Anthropic Messages API) final client = ClaudeClient( apiKey: Platform.environment['ANTHROPIC_API_KEY'] ?? '', ); // AWS Bedrock(Claude,使用 SigV4 认证) final client = BedrockClaudeClient( region: 'us-east-1', accessKeyId: Platform.environment['AWS_ACCESS_KEY_ID'] ?? '', secretAccessKey: Platform.environment['AWS_SECRET_ACCESS_KEY'] ?? '', );
此外还支持 Kimi(Moonshot AI)、Qwen(阿里 DashScope)、Zhipu GLM、豆包 Seed、MiniMax 等国产模型,以及 Ollama(本地模型)和 OpenRouter(统一路由)。
技能系统:让 Agent 按需加载能力
Dart Agent Core 支持两种技能模式,让 Agent 能动态加载和卸载能力模块,避免上下文窗口被无关 prompt 占满。
Pure Dart Skills 将系统 prompt 和工具绑定在一起:
class CodeReviewSkill extends Skill {
CodeReviewSkill() : super(
name: 'code_review',
description: 'Review code for bugs and style issues.',
systemPrompt: 'You are an expert code reviewer...',
tools: [readFileTool, lintTool],
);
}
final agent = StatefulAgent(
skills: [CodeReviewSkill(), DataAnalysisSkill()],
);
技能默认是惰性激活的——Agent 通过内置的 activate_skills / deactivate_skills 工具,在需要时动态启用。也可以设置 forceActivate: true 让技能常驻。
文件系统技能则从本地目录加载 SKILL.md 文件,支持 JavaScript 脚本执行:
final agent = StatefulAgent( skillDirectoryPath: '/path/to/skills_root', javaScriptRuntime: NodeJavaScriptRuntime(), );
当配置了 javaScriptRuntime 时,框架会暴露 RunJavaScript 工具,让 Agent 能执行本地 JS 脚本。在 Flutter 中,可以通过 flutter_js 包实现:
final agent = StatefulAgent(
javaScriptRuntime: FlutterJavaScriptRuntime(
runtime: flutter_js.getJavascriptRuntime(),
),
);
// 注册桥接通道,让 JS 调用 native 能力
agent.registerJavaScriptBridgeChannel('local.greeting', (payload, context) {
final name = (payload['name'] ?? 'friend').toString();
return {'message': 'Hello, $name'};
});
子代理调度:多 Agent 协作
复杂任务可以拆解给多个子代理并行处理。每个子代理有自己的隔离状态:
final agent = StatefulAgent(
subAgents: [
SubAgent(
name: 'researcher',
description: 'Searches the web and summarizes findings.',
agentFactory: (parent) => StatefulAgent(
name: 'researcher',
client: parent.client,
modelConfig: parent.modelConfig,
state: AgentState.empty(),
tools: [webSearchTool],
isSubAgent: true,
),
),
],
);
主 Agent 通过内置 delegate_task 工具调度任务:assignee: 'clone' 克隆当前 Agent 的副本,assignee: 'researcher' 使用指定的子代理。
流式输出与实时 UI
在 Flutter 中做实时 UI 更新,使用 runStream() 替代 run():
await for (final event in agent.runStream([UserMessage.text('Hello')])) {
switch (event.eventType) {
case StreamingEventType.modelChunkMessage:
// 流式文本逐块更新 UI
break;
case StreamingEventType.functionCallRequest:
// 模型请求调用工具
break;
case StreamingEventType.functionCallResult:
// 工具执行完成
break;
}
}
Agent Hooks:在管线中插一脚
如果你需要在 Agent 执行的特定阶段插入自定义逻辑,Agent Hooks 是最灵活的方式。支持的钩子点包括:beforeRun、beforeModelCall、afterModelCall、beforeToolCall、afterToolCall 等。
class DeleteFilePolicyHook extends AgentHook {
@override
ToolCallHookResult beforeToolCall(ToolCallHookContext context) {
if (context.call.name != 'delete_file') {
return ToolCallHookResult.proceed(context.call);
}
return ToolCallHookResult.deny(
content: [TextPart('delete_file is blocked by local policy.')],
);
}
}
final agent = StatefulAgent(
hooks: [DeleteFilePolicyHook()],
);
这个例子展示了如何在工具调用之前进行安全策略拦截——对于生产环境的 Agent 来说,这是必不可少的能力。
会话压缩与长期记忆
长时间运行的 Agent 会积累大量上下文。Dart Agent Core 的 LLMBasedContextCompressor 能在 token 数超过阈值时自动压缩旧消息为情景记忆:
final agent = StatefulAgent(
compressor: LLMBasedContextCompressor(
client: client,
modelConfig: ModelConfig(model: 'gpt-4o-mini'),
totalTokenThreshold: 64000,
keepRecentMessageSize: 10,
),
);
Agent 可以通过内置的 retrieve_memory 工具在被压缩的记忆中检索原始信息,兼顾长上下文和 token 成本。
适合哪些场景?
Dart Agent Core 最适合的用法不是替代后端服务,而是在移动端或桌面端直接运行轻量 Agent的场景:
- 本地助手:在 Flutter 桌面应用中嵌入一个能操作本地文件的 AI 助手
- 离线优先:搭配 Ollama 等本地模型,在网络不稳定的环境中运行
- 原型验证:快速在移动端验证 Agent 交互流程,确认后再考虑后端化
- Web 嵌入式工具:在 WASM 环境中运行单次工具调用,零服务器成本
如果你正在用 Flutter 开发,并且想让你的应用拥有一个真正的 AI Agent(不只是调 API 聊天),Dart Agent Core 提供了一个完整的、纯 Dart 的解决方案。MIT 许可证,31⭐,文档完善,上手门槛很低。
相关链接: