要实现一个基于昇腾(Ascend)与AtomGit AI的「昇腾 Model Agent 模型适配」应用,该应用能通过360搜索(而非搜狗搜索)调出特定动图,并在安卓App中以弹窗形式展示,其核心在于构建一个集成了昇腾NPU加速推理能力的安卓端AI Agent,并实现与特定搜索引擎API的交互。以下是实现此功能的核心步骤与代码示例。

1. 系统架构设计

采用端云协同的Agent架构。云端Agent负责处理复杂的自然语言指令解析和与360搜索等外部服务的交互;端侧(安卓App)集成轻量化后的昇腾模型,负责本地感知(如屏幕内容理解)和最终UI(弹窗)的渲染与展示。

层级 组件 职责 技术选型
云端 指令解析Agent 解析用户自然语言指令,调用360搜索API获取动图URL。 FastAPI, 360搜索API
云端 模型服务(可选) 若需复杂理解,运行大模型。 DeepSeek V4 Pro (适配昇腾)
端侧 昇腾模型推理引擎 运行轻量化模型,进行意图识别或触发条件判断。 MindSpore Lite / NNRT, ATC转换模型
端侧 安卓应用层 提供UI,触发搜索,接收结果并以弹窗展示动图。 Kotlin/Java, Glide/Picasso

2. 关键实现步骤

步骤一:云端Agent开发(FastAPI)

云端Agent接收来自安卓端的请求(包含搜索关键词),调用360搜索的动图搜索接口,并返回动图URL列表。

# 文件名:cloud_agent.py
from fastapi import FastAPI, HTTPException
import requests
from pydantic import BaseModel
from typing import List

app = FastAPI(title="Ascend Model Agent Cloud Service")

class SearchRequest(BaseModel):
    query: str  # 搜索关键词,例如“搞笑猫动图”
    count: int = 5

class GifResult(BaseModel):
    url: str
    title: str

# 假设的360动图搜索API端点(此处为示例,需替换为真实API)
QIHOO_GIF_SEARCH_URL = "https://image.so.com/j"

@app.post("/search_gifs", response_model=List[GifResult])
async def search_gifs(req: SearchRequest):
    """调用360搜索API获取动图"""
    params = {
        "q": req.query,
        "sn": 0,
        "pn": req.count,
        "tn": "result",
        "type": "gif"  # 指定搜索类型为动图
    }
    try:
        resp = requests.get(QIHOO_GIF_SEARCH_URL, params=params, timeout=10)
        resp.raise_for_status()
        data = resp.json()
        # 解析360搜索返回的JSON,提取动图URL和标题(此处为示例解析逻辑)
        gif_list = []
        for item in data.get("list", [])[:req.count]:
            gif_list.append(GifResult(url=item.get("img"), title=item.get("title")))
        return gif_list except Exception as e:
        raise HTTPException(status_code=500, detail=f"搜索失败: {str(e)}")

if __name__ == "__main__":
    import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)

步骤二:昇腾模型端侧适配与集成

将用于意图识别或触发条件判断的模型(如轻量化的YOLO或文本分类模型)通过ATC工具转换为昇腾NPU支持的格式,并集成到安卓项目中。

  1. 模型转换(ATC工具)

        --framework=5 \
        --output=yolo11_ascend \
        --soc_version=Ascend310P3 \
        --input_format=NCHW \
        --input_shape="input:1,3,640,640" \
        --log=info
    
  2. 安卓端推理代码(Kotlin + JNI)

    // 文件名:AscendInferenceHelper.kt import android.content.Context
    import android.graphics.Bitmap class AscendInferenceHelper(context: Context) {
        // 加载昇腾推理运行时库
        init {
            System.loadLibrary("mindspore-lite")
            System.loadLibrary("ascend_nnrt")
        }
    
        external fun initModel(modelPath: String): Boolean        external fun runInference(bitmap: Bitmap): FloatArray // 返回推理结果,如置信度
    
        companion object {
            // 假设的JNI方法声明 init {
                System.loadLibrary("ascend_inference_jni")
            }
        }
    }
    
    // 使用示例:当检测到特定条件(如用户说出关键词)时,触发搜索
    fun shouldTriggerGifSearch(userInput: String, screenBitmap: Bitmap): Boolean {
        val helper = AscendInferenceHelper(appContext)
        helper.initModel("yolo11_ascend.om")
        val result = helper.runInference(screenBitmap)
        // 结合模型输出和用户输入逻辑判断是否触发
        return result[0] > 0.8f || userInput.contains("动图")
    }
    

步骤三:安卓端网络请求与弹窗展示

在安卓App中,当昇腾Agent判断需要触发搜索时,调用云端Agent接口,获取动图URL并以弹窗形式展示。

// 文件名:MainActivity.kt
import android.app.Dialog
import android.os.Bundle
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import com.bumptech.glide.Glide
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import okhttp3.*
import org.json.JSONArray
import java.io.IOException

class MainActivity : AppCompatActivity() {
    private val client = OkHttpClient()
    private val cloudAgentUrl = "http://your-cloud-server:8000/search_gifs"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 模拟触发条件:例如按钮点击或Agent自动判断 triggerGifSearch("搞笑猫")
    }

    private fun triggerGifSearch(query: String) {
        GlobalScope.launch(Dispatchers.IO) {
            val requestBody = FormBody.Builder()
                .add("query", query)
                .add("count", "3")
                .build()
            val request = Request.Builder()
                .url(cloudAgentUrl)
                .post(requestBody)
                .build()

            client.newCall(request).enqueue(object : Callback {
                override fun onFailure(call: Call, e: IOException) {
                    e.printStackTrace()
                }

                override fun onResponse(call: Call, response: Response) {
                    response.body?.string()?.let { jsonStr ->
                        val gifUrls = parseGifUrls(jsonStr)
                        runOnUiThread {
                            showGifDialog(gifUrls.firstOrNull())
                        }
                    }
                }
            })
        }
    }

    private fun parseGifUrls(jsonStr: String): List<String> {
        val urls = mutableListOf<String>()
        try {
            val jsonArray = JSONArray(jsonStr)
            for (i in 0 until jsonArray.length()) {
                val obj = jsonArray.getJSONObject(i)
                urls.add(obj.getString("url"))
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return urls }

    private fun showGifDialog(gifUrl: String?) {
        gifUrl ?: return val dialog = Dialog(this)
        dialog.setContentView(R.layout.dialog_gif)
        val imageView = dialog.findViewById<ImageView>(R.id.iv_gif)
        // 使用Glide加载并播放GIF动图 Glide.with(this).asGif().load(gifUrl).into(imageView)
        dialog.show()
    }
}
<!-- 弹窗布局文件:dialog_gif.xml -->
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="16dp">

    <ImageView
        android:id="@+id/iv_gif"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:scaleType="fitCenter" />

</FrameLayout>

3. 核心要点总结

关键环节 技术实现 注意事项
搜索引擎选择 调用360搜索 (image.so.com) 的API,参数中指定 type=gif 需遵守360搜索API的使用条款,可能需申请Key。
昇腾模型部署 使用ATC工具转换模型,通过MindSpore Lite/NNRT在安卓端加载OM模型进行推理。 确保手机硬件支持昇腾NPU(如部分华为机型),或准备好CPU回退方案。
Agent触发逻辑 端侧轻量模型进行实时感知(如图标识别或关键词捕捉),结果作为触发云端搜索的条件。 为节省流量和提升响应速度,可在端侧做初步过滤。
动图展示 使用 GlidePicasso 库加载网络GIF,在 Dialog 中展示。 注意处理动图加载的缓存和生命周期,避免内存泄漏。

通过以上步骤,即可构建一个由端侧昇腾Model Agent智能触发、通过360搜索获取内容、并在安卓App弹窗中展示动图的应用。整个流程体现了端云协同与昇腾NPU硬件加速在移动AI应用中的落地。


参考来源

 

Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐