news 2026/6/13 2:12:53

鸿蒙 + Flutter 下如何管理 AI 会话——AgentService 设计解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙 + Flutter 下如何管理 AI 会话——AgentService 设计解析

适合谁看

  • 正在给鸿蒙 Flutter 应用接 AI 会话的人

  • 想把模型调用从页面层抽出来的人

  • 想理解移动端(尤其是鸿蒙端)AI 会话管理该收在哪一层的人

  • 想了解 AgentService 如何和协调器、工具层、鸿蒙原生能力协作的人

问题背景

很多 AI 页面初版都会直接这样写:

  • 页面按钮点一下

  • 直接发请求

  • 把结果塞回状态

这种方式在 Demo 阶段很快,但一旦开始加入:

  • 工具调用

  • 流式输出

  • 会话记忆

  • 页面退出释放

  • 鸿蒙端的语音输入输出联动

  • Token 消耗统计和成本追踪

页面层就会很快变得过重。

真正的难点不是"怎么发一次聊天请求",而是:

怎么让移动端里的 AI 会话成为一个可管理对象——在鸿蒙设备上尤其如此,因为会话生命周期还要和鸿蒙原生引擎的生命周期对齐。

项目中的真实场景

食界探味当前专门抽了:

  • app/lib/core/ai/agent_service.dart— AI 会话服务层

它上面连接:

  • app/lib/core/ai/agent_providers.dart— 模型配置和 Provider

下面被:

  • app/lib/core/ai/ai_explore_coordinator.dart— 协调器消费

同时它间接触发鸿蒙侧的能力:

  • SpeechRecognitionPlugin.ets— 语音识别

  • TextToSpeechPlugin.ets— TTS 播报

这说明当前项目并没有让页面直接依赖 AI Provider,而是先放了一层专门的会话服务。这个服务层不感知底层是鸿蒙还是 Android,但它的生命周期管理直接影响鸿蒙端的体验。

核心实现

先说结论:

AgentService的价值不在"帮你少写几行调用代码",而在"把 AI 会话的创建、使用、续跑和释放都变成可管理的结构"。

一、它先把"当前会话对象"收成了显式状态

AgentService里,最关键的一个字段是:

class AgentService { final OpenAIProvider _provider; AIAgent? _currentAgent;

这说明项目当前对 AI 会话的理解不是"随手发一次模型请求",而是"当前有一个会话中的 agent"。这一步很重要,因为它让创建 agent、使用 agent、清掉 agent 这些动作都有了明确落点。

二、Provider 层:模型配置和成本追踪

在深入AgentService之前,先看它依赖的 Provider 层:

// app/lib/core/ai/agent_providers.dart final zhipuAIProvider = Provider<OpenAIProvider>((ref) { return OpenAIProvider( config: OpenAIConfig( baseUrl: '${EnvConfig.apiBaseUrl}/zhipu/paas/v4', apiKey: 'proxy-managed', model: 'glm-4.7', ), ); });

这里有几个值得注意的设计:

  1. API Key 由后端代理管理— 客户端持有的是proxy-managed占位符,真实的 API Key 在后端注入。这对鸿蒙端的安全性尤其重要,避免密钥暴露在客户端代码中

  2. 通过后端代理转发— 请求走${EnvConfig.apiBaseUrl}/zhipu/paas/v4,而不是直连智谱 API。这意味着鸿蒙设备即使在受限网络环境下也能正常访问

  3. 模型可切换— 项目维护了一个允许使用的模型列表:

const zhipuAllowedModels = [ 'glm-4v-flash', 'glm-4-flash', 'glm-4v', 'glm-4v-plus', 'glm-4.5v', 'glm-4.6', 'glm-4.6v', 'glm-4.7', ];
  1. Token 成本追踪— 每次对话完成后,AgentService会记录消耗的 token 数量和费用:

if (chunk.isDone && chunk.usage != null) { AppLogger.info( '[AgentService] 消耗: ${ZhipuPricing.formatCostLog(chunk.usage!)}', ); }

成本计算逻辑:

class ZhipuPricing { static const double inputPricePerMillion = 3.0; // 输入 ¥3/百万 token static const double outputPricePerMillion = 14.0; // 输出 ¥14/百万 token static String formatCostLog(TokenUsage usage) { final inputCost = usage.promptTokens * inputPricePerMillion / 1000000; final outputCost = usage.completionTokens * outputPricePerMillion / 1000000; final totalCost = inputCost + outputCost; return '输入: ${usage.promptTokens} tokens (¥${inputCost.toStringAsFixed(6)}), ' '输出: ${usage.completionTokens} tokens (¥${outputCost.toStringAsFixed(6)}), ' '总计: ${usage.totalTokens} tokens (¥${totalCost.toStringAsFixed(6)})'; } }

在鸿蒙端调试时,这些日志能帮你快速判断:模型调用是否正常、token 消耗是否合理、成本是否可控。

三、createAgent()让会话初始化集中发生

createAgent()当前做的事情并不只是"new 一个对象",而是把一组会话初始条件都收在了一起:

AIAgent createAgent({ required String systemPrompt, List<Tool>? tools, String? model, int maxMessages = 50, bool enableAutoToolExecution = false, }) { final agent = AIAgent( provider: _provider, config: AIAgentConfig( systemPrompt: systemPrompt, model: model, enableAutoToolExecution: enableAutoToolExecution, additionalParams: {'thinking': {'type': 'disabled'}}, ), memoryManager: ConversationMemory(maxMessages: maxMessages), ); if (tools != null) { for (final tool in tools) { agent.addTool(tool); } } _currentAgent = agent; return agent; }

各参数的职责:

参数

作用

为什么放在服务层

systemPrompt

定义 AI 的角色和行为规范

避免每个页面重复写 prompt

tools

注册业务工具(搜索菜品、详情等)

工具注册逻辑统一收口

model

指定模型名称,默认用 Provider 配置

支持按场景切换模型

maxMessages

记忆窗口大小,控制历史消息保留数量

移动端内存有限,必须主动控制

enableAutoToolExecution

是否自动执行工具调用

避免协调器手动管理工具执行

注意additionalParams: {'thinking': {'type': 'disabled'}}— 这禁用了模型的思考链输出。在移动端,思考链会增加延迟和 token 消耗,禁用后响应更快。

这说明AgentService当前其实已经在承担agent 工厂 + 会话策略入口的职责。页面层和协调器层不再需要自己拼这些初始条件。

四、为什么记忆窗口要留在这层

createAgent()里,ConversationMemory(maxMessages: maxMessages)是一个很值得注意的点。

它说明项目已经意识到:移动端 AI 会话不是无限上下文,而应该主动控制会话窗口大小和历史消息保留数量。

食界探味在协调器中实际使用的配置:

// ai_explore_coordinator.dart _agentService.createAgent( systemPrompt: _systemPrompt, tools: [...], enableAutoToolExecution: true, maxMessages: 30, // 最多保留 30 条历史消息 );

为什么是 30?因为:

  1. 鸿蒙端设备内存有限,过多历史消息会占用大量内存

  2. 菜品推荐场景不需要太长的对话历史

  3. 30 条足够覆盖 10-15 轮对话,满足"探索 → 细化 → 推荐"的典型流程

这类决策如果直接塞进页面层,后面会很难统一。放在AgentService里就更合理,因为它更接近"会话策略",而不是"页面渲染策略"。

五、为什么流式对话也应该收在这层

chatWithToolsStream()是这份代码里最关键的方法之一:

Future<void> chatWithToolsStream({ required String message, AIAgent? agent, void Function(String)? onThinking, void Function(String)? onContent, void Function(ToolCall)? onToolCall, void Function(String)? onComplete, }) async { final targetAgent = agent ?? _currentAgent; if (targetAgent == null) { throw StateError('没有可用的 Agent,请先调用 createAgent()'); } await for (final chunk in targetAgent.chatStreamRaw(message)) { // 1. 思考内容(已禁用,但保留接口) if (chunk.reasoningContent != null && onThinking != null) { onThinking(chunk.reasoningContent!); } // 2. 增量文本(流式输出给页面展示) if (chunk.content != null && onContent != null) { onContent(chunk.content!); } // 3. 工具调用(模型决定调用业务工具) if (chunk.toolCalls != null && chunk.toolCalls!.isNotEmpty && onToolCall != null) { for (final toolCall in chunk.toolCalls!) { onToolCall(toolCall); } } // 4. 完成时记录 token 消耗 if (chunk.isDone && chunk.usage != null) { AppLogger.info( '[AgentService] 消耗: ${ZhipuPricing.formatCostLog(chunk.usage!)}', ); } }

这段代码把流式的四个阶段统一收口了:

用户消息 → [reasoningContent] → [content] → [toolCalls] → [isDone + usage] ↑ 思考(已禁用) ↑ 文本输出 ↑ 工具调用 ↑ 完成统计

协调器只需要关注回调,不需要理解底层 chunk 结构:

// ai_explore_coordinator.dart await _agentService.chatWithToolsStream( message: text, onContent: (chunk) { // 只关心:文本增量来了,更新页面 buffer.write(chunk); state = state.copyWith( status: AiSessionStatus.responding, streamingText: buffer.toString(), ); }, onToolCall: (toolCall) { // 只关心:模型在调用工具,更新状态为"搜索中" state = state.copyWith(status: AiSessionStatus.searching); }, onComplete: (full) { // 只关心:回复完成 state = state.copyWith(status: AiSessionStatus.idle, streamingText: full); }, );

这样做的好处是:协调器层不需要直接理解底层流对象细节,页面层更不需要直接碰这些底层 chunk 结构。

六、工具调用为什么也放在这里处理

chatWithToolsStream()在流式对话结束后,还会自动检测并执行待执行的工具调用:

// 如果有待执行的工具调用,自动执行并继续对话 if (targetAgent.pendingToolCalls != null && targetAgent.pendingToolCalls!.isNotEmpty) { await for (final chunk in targetAgent.executeToolsAndContinue()) { if (chunk.content != null && onContent != null) { onContent(chunk.content!); } if (chunk.isDone && chunk.fullContent != null && onComplete != null) { onComplete(chunk.fullContent!); } if (chunk.isDone && chunk.usage != null) { AppLogger.info( '[AgentService] 工具回调消耗: ${ZhipuPricing.formatCostLog(chunk.usage!)}', ); } } }

这意味着一次完整的 AI 交互可能是这样的:

用户: "推荐牛肉吃法" ↓ AgentService: 调用 chatWithToolsStream ↓ 模型: 返回 tool_call: search_dishes({ingredients: ["牛肉"]}) ↓ AgentService: 检测到 pendingToolCalls,自动执行 executeToolsAndContinue ↓ 工具: 查询数据库,返回 5 道牛肉菜品 ↓ 模型: 基于工具结果生成推荐文案 ↓ AgentService: 通过 onContent 回调把文案流式输出 ↓ 协调器: 收到文案 + matchedDishes,更新页面状态

关键在于:工具执行和继续对话的逻辑完全在 AgentService 内部完成,协调器不需要手动管理这个循环。如果这部分留在页面层或者每个协调器里各自拼,后面很容易变成每个页面有自己的一套工具续跑逻辑。

七、为什么clearCurrentAgent()很关键

很多移动端 AI 功能一开始都会忽略这一点:页面退出了,会话要不要清。

食界探味当前已经明确给了:

void clearCurrentAgent() { _currentAgent?.clearHistory(); // 清除对话历史 _currentAgent = null; // 释放引用 }

协调器在两个场景下会调用它:

  1. 重置会话— 用户点击"新对话"按钮:

// ai_explore_coordinator.dart void reset() { _agentService.clearCurrentAgent(); _agentInitialized = false; if (mounted) { state = const AiSessionState(); } }
  1. 重新初始化— 每个 coordinator 实例首次调用时,先清掉旧 agent 再创建新的:

void _ensureAgent() { if (_agentInitialized) return; _agentInitialized = true; _agentService.clearCurrentAgent(); // 先清旧的 _agentService.createAgent( // 再建新的 systemPrompt: _systemPrompt, tools: [...], enableAutoToolExecution: true, maxMessages: 30, ); }

这说明当前项目并没有把 AI 会话默认当成永久全局状态,而是允许某个页面会话结束后重置。这对鸿蒙端来说尤其重要,因为:

  • 鸿蒙设备内存管理更严格,长期悬挂的会话对象会占用不可回收的内存

  • 鸿蒙的页面生命周期和 Android 不完全一致,需要更主动地管理资源

  • 用户在鸿蒙设备上切换应用再回来时,会话状态应该被正确恢复或清理

八、为什么dispose()必须放在服务层

在当前代码里,dispose()最后还会调用_provider.dispose()

void dispose() { _currentAgent = null; _provider.dispose(); // 释放底层模型 Provider }

同时 Riverpod Provider 也在onDispose时触发了这件事:

final agentServiceProvider = Provider<AgentService>((ref) { final provider = ref.watch(zhipuAIProvider); final service = AgentService(provider); ref.onDispose(() => service.dispose()); // Provider 销毁时自动释放 return service; });

这说明当前结构非常明确地把 AI 资源释放责任收到了服务层,而不是页面层自己猜什么时候释放。这一步很重要,因为 AI Provider、会话对象和流式任务都可能比普通页面状态更重。

在鸿蒙端,资源释放尤其关键:

  1. 鸿蒙的内存回收机制和 Android 不同— 不能依赖 GC 自动回收大对象

  2. 流式任务必须显式取消— 如果页面退出时还有 pending 的流式请求,必须中止

  3. Provider 的 dispose 时机和页面对齐— Riverpod 的autoDispose会自动处理,但前提是服务层的dispose()实现正确

九、协调器如何消费 AgentService

理解了 AgentService 的设计后,再看协调器是怎么用它的:

class AiExploreCoordinator extends StateNotifier<AiSessionState> { final AgentService _agentService; final FoodRepository _foodRepository; // ... 初始化 ... void _ensureAgent() { if (_agentInitialized) return; _agentInitialized = true; _agentService.clearCurrentAgent(); _agentService.createAgent( systemPrompt: _systemPrompt, tools: [ SearchDishesTool(_foodRepository, onDishesFound: _onDishesFound), GetDishDetailTool(_foodRepository), GetRandomDishTool(_foodRepository, onDishesFound: _onDishesFound), GetDishesByIngredientTool(_foodRepository, onDishesFound: _onDishesFound), ], enableAutoToolExecution: true, maxMessages: 30, ); }

协调器向 AgentService 注册了 4 个业务工具:

工具

功能

回调

SearchDishesTool

根据食材/口味/地域搜索菜品

onDishesFound→ 更新matchedDishes

GetDishDetailTool

获取某道菜的详细信息

无(直接返回文本)

GetRandomDishTool

随机推荐一道菜

onDishesFound→ 更新matchedDishes

GetDishesByIngredientTool

按食材查同食材的其他吃法

onDishesFound→ 更新matchedDishes

注意工具的onDishesFound回调——它直接把查询到的菜品数据推给协调器的状态,协调器再通过 Riverpod 通知页面渲染菜品卡片。这就是"AI 推荐 + 业务卡片"联动的关键链路。

十、AgentService 在整体架构中的位置

从整体架构看,AgentService 的位置非常清晰:

┌─────────────────────────────────────────────────┐ │ 页面层 │ │ AiAssistantScreen │ │ │ │ │ ▼ │ │ 协调器层 │ │ AiExploreCoordinator │ │ │ │ │ ▼ │ │ 服务层 │ │ AgentService ← agentServiceProvider │ │ │ │ │ ▼ │ │ Provider 层 │ │ zhipuAIProvider → OpenAIProvider │ │ │ │ │ ▼ │ │ 工具层 │ │ SearchDishesTool / GetDishDetailTool / ... │ │ │ ├─────────────────────────────────────────────────┤ │ 鸿蒙原生层(间接) │ │ SpeechRecognitionPlugin TextToSpeechPlugin │ │ ← 通过 Channel 被协调器调用,AgentService 不直接 │ │ 感知,但会话生命周期影响语音体验 │ └─────────────────────────────────────────────────┘

核心要点:

  1. AgentService 不感知鸿蒙— 它是纯 Flutter/AI 服务层,不 import 任何鸿蒙相关代码

  2. 协调器是鸿蒙和 AI 的桥梁— 它同时调用 AgentService(AI 能力)和 Channel(鸿蒙能力)

  3. 页面层最轻— 只负责 UI 渲染和用户交互,所有 AI/语音逻辑都委托给下层

  4. Provider 层管理依赖— Riverpod 自动处理创建、缓存、销毁的生命周期

关键代码位置

文件

作用

app/lib/core/ai/agent_service.dart

AI 会话服务层

app/lib/core/ai/agent_providers.dart

模型配置、Provider、成本追踪

app/lib/core/ai/ai_explore_coordinator.dart

协调器,消费 AgentService

app/lib/core/ai/models/ai_session_state.dart

会话状态模型

app/lib/core/ai/tools/

4 个业务工具

app/lib/core/platform/speech_recognition_channel.dart

语音识别通道(协调器调用)

app/lib/core/platform/text_to_speech_channel.dart

TTS 通道(协调器调用)

鸿蒙侧与 AgentService 的协作关系

虽然 AgentService 本身是纯 Flutter 层,但它在鸿蒙端的行为有特殊意义:

生命周期对齐

鸿蒙页面创建 → AiAssistantScreen initState → coordinator 创建(Riverpod autoDispose) → AgentService 创建(Provider) → zhipuAIProvider 创建 → OpenAIProvider 初始化 鸿蒙页面销毁 → AiAssistantScreen dispose → coordinator dispose(自动) → AgentService dispose → _currentAgent = null → _provider.dispose()

语音联动时序

用户按住语音按钮 → coordinator.startVoiceInput() → SpeechRecognitionChannel.startListening() [鸿蒙原生] → 用户说话... → 鸿蒙识别完成,返回文本 → coordinator.submitQuery(text) → AgentService.chatWithToolsStream() → 模型推理 + 工具调用 → 流式输出 → coordinator.speakText(response) → TextToSpeechChannel.speak() [鸿蒙原生] → 鸿蒙 TTS 引擎播报 → 用户退出页面 → coordinator dispose → TextToSpeechChannel.stop() [鸿蒙原生] → 鸿蒙 TTS 引擎停止

在这个流程中,AgentService 不直接调用任何鸿蒙 API,但它的chatWithToolsStream是整个链路的核心——所有 AI 推理和工具调用都在这里完成。协调器负责把鸿蒙的语音输入喂给 AgentService,再把 AgentService 的输出喂给鸿蒙的 TTS。

资源管理对比

场景

Android 行为

鸿蒙行为

AgentService 的应对

页面退出

Activity 销毁,GC 回收

Ability 组件销毁,内存管理更严格

dispose()显式释放

流式中断

网络断开,chunk 停止

网络切换(WiFi→移动数据),chunk 可能中断

mounted检查 + 异常捕获

后台切回

onResume,状态恢复

前后台切换,Ability 状态恢复

Riverpod autoDispose 自动管理

内存不足

系统杀进程

系统回收 Ability

clearCurrentAgent()主动释放

常见坑

  • 页面层直接 new agent,导致会话生命周期四处散落 → 一定要通过 AgentService 集中管理

  • 工具调用逻辑分散在多个页面或协调器里→ 统一注册到 AgentService,通过enableAutoToolExecution自动执行

  • 流式输出直接在页面层消费底层 chunk→ 用 AgentService 的回调封装,页面只关心文本增量

  • 没有显式清理当前会话,导致状态长期悬挂 → 调用clearCurrentAgent(),尤其是页面退出时

  • 鸿蒙端不主动释放 Provider,导致内存泄漏 → 确保ref.onDispose正确注册

  • API Key 硬编码在客户端→ 走后端代理,客户端只持占位符

  • 记忆窗口设得太大,鸿蒙设备内存吃紧 → 移动端建议 30-50 条,按场景调整

  • 流式任务没有 mounted 检查,页面退出后继续更新状态 → 协调器每个回调开头加if (!mounted) return

可复用模板

如果你要在自己的鸿蒙 + Flutter 项目里做类似的 AI 会话管理,可以参考这个结构:

AgentService 模板

class AgentService { final OpenAIProvider _provider; AIAgent? _currentAgent; AgentService(this._provider); AIAgent? get currentAgent => _currentAgent; AIAgent createAgent({ required String systemPrompt, List<Tool>? tools, String? model, int maxMessages = 50, bool enableAutoToolExecution = false, }) { final agent = AIAgent( provider: _provider, config: AIAgentConfig( systemPrompt: systemPrompt, model: model, enableAutoToolExecution: enableAutoToolExecution, ), memoryManager: ConversationMemory(maxMessages: maxMessages), ); if (tools != null) { for (final tool in tools) { agent.addTool(tool); } } _currentAgent = agent; return agent; } Future<void> chatWithToolsStream({ required String message, AIAgent? agent, void Function(String)? onContent, void Function(ToolCall)? onToolCall, void Function(String)? onComplete, }) async { final targetAgent = agent ?? _currentAgent; if (targetAgent == null) { throw StateError('没有可用的 Agent,请先调用 createAgent()'); } await for (final chunk in targetAgent.chatStreamRaw(message)) { if (chunk.content != null && onContent != null) { onContent(chunk.content!); } if (chunk.toolCalls != null && chunk.toolCalls!.isNotEmpty) { for (final toolCall in chunk.toolCalls!) { onToolCall?.call(toolCall); } } } // 自动执行工具调用并继续对话 if (targetAgent.pendingToolCalls != null && targetAgent.pendingToolCalls!.isNotEmpty) { await for (final chunk in targetAgent.executeToolsAndContinue()) { if (chunk.content != null && onContent != null) { onContent(chunk.content!); } if (chunk.isDone && chunk.fullContent != null) { onComplete?.call(chunk.fullContent!); } } } } void clearCurrentAgent() { _currentAgent?.clearHistory(); _currentAgent = null; } void dispose() { _currentAgent = null; _provider.dispose(); } }

Riverpod Provider 模板

final agentServiceProvider = Provider<AgentService>((ref) { final provider = ref.watch(zhipuAIProvider); final service = AgentService(provider); ref.onDispose(() => service.dispose()); return service; });

协调器消费模板

class AiCoordinator extends StateNotifier<AiSessionState> { final AgentService _agentService; bool _agentInitialized = false; void _ensureAgent() { if (_agentInitialized) return; _agentInitialized = true; _agentService.clearCurrentAgent(); _agentService.createAgent( systemPrompt: '你的系统提示词...', tools: [/* 你的工具列表 */], enableAutoToolExecution: true, maxMessages: 30, ); } Future<void> submitQuery(String text) async { _ensureAgent(); final buffer = StringBuffer(); await _agentService.chatWithToolsStream( message: text, onContent: (chunk) { buffer.write(chunk); state = state.copyWith(streamingText: buffer.toString()); }, onToolCall: (toolCall) { state = state.copyWith(status: AiSessionStatus.searching); }, onComplete: (full) { state = state.copyWith(status: AiSessionStatus.idle); }, ); } void reset() { _agentService.clearCurrentAgent(); _agentInitialized = false; state = const AiSessionState(); } }

本篇总结

AgentService在食界探味里的价值,是把 AI 从"页面里发一次请求"提升成了"移动端里一个可管理的会话对象"。

这层一旦单独成立:

  • 页面层只关心 UI 渲染,不碰模型细节

  • 协调器层专注于产品流程编排,通过 AgentService 的回调驱动状态

  • 工具层统一注册到 AgentService,不分散在各处

  • 鸿蒙原生能力由协调器直接调用,AgentService 保持平台无关

  • 资源生命周期由 Riverpod Provider 统一管理,确保鸿蒙端不泄漏

在鸿蒙设备上,这套分层让 AI 助手既能享受 Flutter 的跨平台 UI 能力,又能无缝接入鸿蒙的语音识别和 TTS 能力,同时保持了清晰的职责边界和资源管理。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/13 2:12:39

3步彻底解放双手:i茅台自动预约系统终极指南

3步彻底解放双手&#xff1a;i茅台自动预约系统终极指南 【免费下载链接】campus-imaotai i茅台app自动预约&#xff0c;每日自动预约&#xff0c;支持docker一键部署&#xff08;本项目不提供成品&#xff0c;使用的是已淘汰的算法&#xff09; 项目地址: https://gitcode.c…

作者头像 李华
网站建设 2026/6/13 1:59:53

告别手动调参!用Geolitix的批处理功能,5分钟搞定GPR数据预处理全流程

告别手动调参&#xff01;用Geolitix的批处理功能&#xff0c;5分钟搞定GPR数据预处理全流程地质雷达&#xff08;GPR&#xff09;技术已成为现代工程勘察和地质探测中不可或缺的工具&#xff0c;但海量数据的预处理工作往往让技术人员陷入重复劳动的泥潭。传统软件中逐个文件调…

作者头像 李华
网站建设 2026/6/13 1:58:08

LLM路由优化:三维评估框架与Dirichlet聚合实践

1. 项目概述&#xff1a;协作式LLM系统中的路由挑战 在当今AI应用场景中&#xff0c;大型语言模型&#xff08;LLM&#xff09;面临着成本与性能的永恒博弈。RouterXBench针对这一核心矛盾&#xff0c;提出了一个系统性的解决方案。想象一下医院问诊场景&#xff1a;常规症状咨…

作者头像 李华