【从 ima-skills 到 WeKnora:Agent Skill 能不能直接接企业级 RAG?一次把原理讲清楚】

从 ima-skills 到 WeKnora

摘要:本文串起 ima-skills 与 WeKnora:先讲 Agent Skill 如何把自然语言翻译成 API,再拆解为何不能只改域名硬接,并给出适配方案。

写在前面

最近做了一次小调研:ima-skills 能不能接入内网私有化部署的 WeKnora?

这个问题看起来像是"把接口地址从 A 改成 B"这么简单,但真正拆下去会发现:它其实考的是三件事:

  1. Agent Skill 到底是什么?
  2. 企业级 RAG 平台到底做了什么?
  3. 两个系统的 API、鉴权、数据模型不一致时,应该硬改还是做适配?

所以这篇文章我会先分别介绍两个主角,再讲它们为什么不能直接相连,最后给出一个更稳的改造思路。

ima-skills

ima-skills 可以先理解成:给 Agent 用的一套"操作说明书 + 工具脚本"。

它本身不是大模型,也不是知识库数据库,而是告诉 Agent:

当用户说"帮我把这个文件上传到知识库""搜一下我的资料库""记一条笔记"时,你应该调用哪个模块、拼什么参数、走哪个 IMA OpenAPI。

更具体一点,它主要覆盖两类能力:

模块 解决什么问题 典型用户表达
notes 管理个人笔记 "帮我新建一篇笔记""搜索会议纪要"
knowledge-base 管理 IMA 知识库资源 "上传文件到知识库""把网页加入资料库""搜索知识库"

Agent Skill 的关键:它靠"语义触发"

传统程序一般是你点按钮、调函数。

Agent Skill 不太一样。它的入口往往是自然语言:

用户:把这个 PDF 上传到我的产品资料库。

Agent 读到这句话后,会根据 Skill 的说明判断:

判断步骤 Agent 在想什么
识别意图 用户要操作的是"知识库",不是普通聊天
选择模块 应该进入 knowledge-base,不是 notes
选择接口流程 文件上传要走上传链路,而不是搜索接口
构造请求 读取凭证,拼 Header 和 Body,调用 IMA OpenAPI

这就是 ima-skills 最核心的价值:把人的自然语言意图,翻译成 IMA OpenAPI 能理解的 HTTP 请求。

ima-skills 的运行链路

可以把它想成一条流水线:

环节 作用
用户意图 用户用自然语言提出需求
Agent 路由 Agent 根据 SKILL.md 判断该用哪个模块
脚本封装 ima_api.cjs 统一处理请求
鉴权信息 读取 Client IDAPI Key
IMA 服务 返回笔记、知识库、上传结果等数据

所以一条完整调用大概是:

用户意图 → Agent 选择 Skill → 进入 notes / knowledge-base → ima_api.cjs 发 HTTP 请求 → IMA 返回结果。

文件上传为什么比搜索复杂?

搜索知识库通常是一个 POST 请求就够了,但文件上传不一样。

在 IMA 的知识库上传链路里,文件不是简单地 multipart/form-data 直接扔给后端,而是更像"先领上传通行证,再把文件放到对象存储,最后登记入库":

步骤 作用
check_repeated_names 检查知识库里有没有同名文件
create_media 向 IMA 申请媒体资源和临时 COS 凭证
COS Upload 使用临时凭证把文件上传到对象存储
add_knowledge 告诉 IMA:文件已经上传好了,请加入知识库

这也是后面"不能直接接 WeKnora"的伏笔之一:上传链路从根上就不是同一种协议。

WeKnora

WeKnora 是腾讯开源的知识管理框架。和 ima-skills 相比,它不是一个轻量工具包,而是一个完整的企业级知识智能底座。

如果说 ima-skills 更像"Agent 操作 IMA 的遥控器",那 WeKnora 更像"自己带解析、检索、推理、权限、观测、部署能力的一整套知识系统"。

官方 README 里对它的定位很清楚:WeKnora 面向企业级文档理解、语义检索与智能推理,围绕 RAG 快速问答、ReAct Agent 智能推理、Wiki 模式 三大能力构建。

WeKnora 主要能做什么?

能力 解释
多格式文档接入 支持 PDF、Word、图片、Excel、Markdown、HTML 等多种格式
文档解析与分块 把大文档拆成适合检索的小片段,同时尽量保留语义完整性
混合检索 结合关键词检索、向量检索、图谱增强等方式找资料
RAG 问答 先检索相关知识,再把知识交给大模型生成回答
ReAct Agent 支持多步推理、工具调用、网络搜索、知识库检索等组合任务
Wiki 模式 从原始文档生成结构化 Markdown Wiki 和知识图谱
私有化部署 支持本地、Docker、Kubernetes 等部署形态
企业权限 支持多租户、RBAC、资源归属、审计日志等企业级能力
可观测性 集成 Langfuse,追踪 Agent 推理、Token、工具调用和流水线

WeKnora 的重点不是"把文件存起来"这么简单,而是把文件变成:

可解析、可检索、可引用、可推理、可持续维护的知识资产。

把原理讲清楚:RAG 到底在跑什么?

很多人第一次听 RAG,会把它理解成"把资料丢给 AI,让 AI 回答"。这个理解不算错,但太粗了。 更准确地说,RAG 是两段式:

阶段 做什么 类比
Retrieval 先从知识库里找相关资料 去图书馆找书和页码
Generation 再把资料交给大模型组织答案 拿着资料写一段解释

一份文档进入 RAG 系统后会发生什么?

假设你上传了一份《产品设计文档.pdf》,系统通常会经历下面几步:

  1. 解析文档

    PDF、Word、图片、表格的结构都不一样,系统要先把它们解析成机器可处理的文本、表格、图片描述等内容。

  2. 切分 Chunk

    大模型和向量检索都不喜欢超长文本,所以需要把文档拆成一段段小片段。这个片段常被叫做 chunk

  3. 生成 Embedding

    系统把每个 chunk 转成向量。向量可以理解成"语义坐标",意思相近的文本,向量距离更近。

  4. 建立索引

    向量会进入向量数据库,关键词会进入倒排索引,图谱关系也可能进入图数据库或关系结构。

  5. 用户提问

    用户问:"这个产品的权限模型怎么设计?"

  6. 多路召回

    系统可能同时用 BM25 找关键词、用向量找语义相近内容、用知识图谱找实体关系。

  7. 重排序

    召回结果不一定都靠谱,所以还要 rerank,把更相关的片段排到前面。

  8. 生成回答

    最后把高质量上下文塞进 Prompt,让大模型生成带依据的回答。

所以,RAG 的关键并不是"让大模型记住所有文档",而是:

提问时把最相关的资料找出来,让大模型基于资料回答。

这也是 WeKnora 这类平台的价值:它把"解析、分块、向量化、检索、重排、生成、引用、观测"串成了完整链路。

核心问题:ima-skills 能不能只改 Base URL 接 WeKnora?

结论先说:不能直接接。

更准确一点:

可以复用 ima-skills 的"Agent 交互语义",但不能复用它绑定 IMA 的底层 API 实现。

为什么?因为两边不是"同一个接口换个域名",而是"两个系统的协议、鉴权、数据结构、上传流程都不同"。

差异一:API 基准路径不同

ima-skills 默认面向 IMA OpenAPI,知识库路径是类似:

系统 API 风格
IMA /openapi/wiki/v1/...
WeKnora /api/v1/...

WeKnora 官方 API 文档里也说明了,它的基础 URL 是 /api/v1,并以 RESTful API 管理知识库、知识、检索、聊天等能力。

这意味着:不是把 https://ima.qq.com 改成内网地址就完事了,后面的路径也对不上。

差异二:鉴权方式不同

IMA 的技能调用依赖:

系统 鉴权方式
IMA Client ID + API Key
WeKnora 请求头 X-API-Key,也可能结合账号体系、RBAC、租户权限

也就是说,IMA 控制台生成的凭证,在 WeKnora 内网服务里没有天然意义。

请求发过去以后,WeKnora 不知道这个 Client ID 是谁,也不会按 IMA 的鉴权逻辑校验它。

所以"改地址硬接"的典型结果就是:

请求能发出去,但鉴权失败,或者参数解析失败。

差异三:文件上传链路完全不同

这是最关键的差异之一。

IMA 文件上传是多段式:

IMA 上传步骤 说明
检查重名 check_repeated_names
创建媒体 create_media
上传 COS 使用临时凭证 PUT 文件
加入知识库 add_knowledge

WeKnora 则更直接。官方文档里的文件上传接口是:

WeKnora 上传方式 说明
POST /knowledge-bases/:id/knowledge/file 使用 multipart/form-data 上传文件创建知识

也就是说,在 WeKnora 里,常见上传可以是这样:

bash 复制代码
# 通过 WeKnora 的 multipart 接口上传文件,创建知识条目。
# 注意:WEKNORA_BASE_URL、WEKNORA_KB_ID、WEKNORA_API_KEY 都建议放在环境变量中,避免把密钥写进代码。
curl --location "$WEKNORA_BASE_URL/api/v1/knowledge-bases/$WEKNORA_KB_ID/knowledge/file" \
  --header "X-API-Key: $WEKNORA_API_KEY" \
  --form "file=@./report.pdf" \
  --form 'enable_multimodel="true"'

你看,IMA 的 create_media → COS PUT → add_knowledge 在这里根本没有一一对应关系。

所以旧流程不是"稍微改一下参数",而是要整体替换。

差异四:搜索与问答不是同一个层级

IMA 的 search_knowledge 更像是在 IMA 知识库体系里搜索文件、文件夹或知识内容。

WeKnora 则至少有两个常见层级:

能力 WeKnora 接口思路
只检索,不总结 POST /api/v1/knowledge-search
检索后生成回答 POST /api/v1/knowledge-chat/:session_id,返回 SSE 流

示例:

bash 复制代码
# 在指定 WeKnora 知识库里搜索相关 chunk。
# 这个接口只返回检索命中的片段,不负责调用大模型总结。
curl --location "$WEKNORA_BASE_URL/api/v1/knowledge-search" \
  --header "X-API-Key: $WEKNORA_API_KEY" \
  --header "Content-Type: application/json" \
  --data "{
    \"query\": \"权限模型怎么设计?\",
    \"knowledge_base_id\": \"$WEKNORA_KB_ID\"
  }"

如果要做真正的 RAG 问答,就应该走聊天接口,它会返回 Server-Sent Events,也就是边生成边推送的流式响应。

差异五:返回结构也不同

IMA 常见响应结构是:

字段 含义
code 状态码,0 表示成功
msg 错误或提示信息
data 业务数据

WeKnora 常见响应结构更像:

字段 含义
success 是否成功
data 业务数据
error 错误信息

这会影响上层 Skill 的解析逻辑。

如果旧代码写死了 code === 0 才算成功,那 WeKnora 返回 success: true 时,旧逻辑可能完全看不懂。

对标一下:ima-skills 和 WeKnora 到底差在哪?

维度 ima-skills / IMA WeKnora 适配建议
定位 Agent 调 IMA 的技能包 企业级 RAG 与 Agent 平台 保留上层意图,替换底层调用
数据接入 IMA 生态内笔记、文件、网页 文件、URL、Markdown、多源同步 上传/导入流程重新映射
文档解析 依赖 IMA 后端能力 多格式解析、分块、向量化、图谱增强 交给 WeKnora 处理
检索能力 IMA 知识库搜索 BM25、Dense、GraphRAG 等多路召回 搜索接口单独适配
Agent 推理 依赖宿主 Agent 内置 ReAct Agent 能力 RAG 问答可映射 chat/agent-chat
鉴权 IMA Client ID + API Key X-API-Key、账号、RBAC 重写鉴权层
上传 create media + COS + add knowledge multipart 上传知识 删除 IMA 上传链路
返回结构 {code,msg,data} {success,data,error} / SSE 做响应归一化
部署形态 依附 IMA 云服务和宿主 Agent 可私有化部署 内网部署更适合 WeKnora

一句话总结:

ima-skills 是"让 Agent 会用 IMA"的轻量操作层;WeKnora 是"企业知识进入 RAG/Agent 体系"的完整能力底座。

正确姿势:做一个 WeKnora 适配层

既然不能直接改地址,那该怎么做?

我更推荐的方式是:保留 Skill 的上层语义,新增 WeKnora 的底层适配。 也就是:

层级 保留还是改造 说明
用户表达 保留 用户仍然可以说"上传文件到知识库""搜索知识库"
Agent 路由 尽量保留 仍然由 Skill 判断上传、搜索、问答等意图
IMA API Client 不复用 新增 weknora_api.cjs
鉴权配置 改造 新增 WEKNORA_BASE_URLWEKNORA_API_KEYWEKNORA_KB_ID
上传流程 改造 从 IMA 三段式改为 WeKnora multipart
搜索流程 改造 映射到 knowledge-searchknowledge-chat
响应解析 改造 把 WeKnora 响应转成 Skill 容易消费的统一结构
notes 模块 暂不迁移 WeKnora 没有 IMA notes 的直接等价模型

可以把这个适配层理解成"翻译官":

Agent 还说原来的话,但翻译官把它翻译成 WeKnora 听得懂的 API。

一个最小适配器应该长什么样?

下面是一个简化版思路。真实项目里还要补错误码、超时、日志脱敏、SSE 解析、文件流处理等细节。

js 复制代码
// 统一封装 WeKnora 请求,让上层 Skill 不直接关心 base URL、鉴权头和错误格式。
async function requestWeKnora(path, options = {}) {
  // 从环境变量读取私有化 WeKnora 地址,避免把部署地址写死在代码里。
  const baseUrl = process.env.WEKNORA_BASE_URL;

  // 从环境变量读取 API Key,避免把密钥提交到仓库或日志中。
  const apiKey = process.env.WEKNORA_API_KEY;

  // 拼出完整 API 地址;path 只表达业务端点,例如 /knowledge-search。
  const url = `${baseUrl.replace(/\/$/, "")}/api/v1${path}`;

  // 发起 HTTP 请求,并统一加上 WeKnora 的 X-API-Key 鉴权头。
  const res = await fetch(url, {
    ...options,
    headers: {
      "X-API-Key": apiKey,
      ...(options.headers || {}),
    },
  });

  // WeKnora 可能用 HTTP 状态码表达错误,这里先做统一兜底。
  if (!res.ok) {
    throw new Error(`WeKnora request failed: ${res.status}`);
  }

  // 返回 JSON 给上层,再由调用方按 success/data/error 做业务解析。
  return res.json();
}

再比如搜索知识库,可以封装成:

js 复制代码
// 把"搜索知识库"的 Skill 意图映射到 WeKnora 的 knowledge-search 接口。
async function searchKnowledge(query, knowledgeBaseId) {
  // 构造 WeKnora 搜索接口需要的请求体。
  const body = JSON.stringify({
    query,
    knowledge_base_id: knowledgeBaseId,
  });

  // 调用 WeKnora 检索接口;该接口返回命中的 chunk,而不是最终总结答案。
  const result = await requestWeKnora("/knowledge-search", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body,
  });

  // 把 WeKnora 的 success/data 结构归一化,方便上层 Skill 使用。
  return {
    code: result.success ? 0 : -1,
    msg: result.success ? "ok" : result.error?.message || "unknown error",
    data: result.data || [],
  };
}

注意这里的重点不是代码本身,而是架构思想:

不要让上层 Agent 到处感知 WeKnora 的接口细节,而是把差异集中收口到适配层。

适配方案清单

如果真要把 ima-skills 的知识库能力迁到 WeKnora,我会按下面顺序做。

1. 配置层

新增三个基础配置:

配置项 作用
WEKNORA_BASE_URL WeKnora 内网服务地址
WEKNORA_API_KEY WeKnora API 鉴权密钥
WEKNORA_KB_ID 默认目标知识库 ID

2. HTTP Client 层

新增 weknora_api.cjs,不要直接魔改 ima_api.cjs

原因很简单:

做法 风险
直接改 ima_api.cjs IMA 与 WeKnora 逻辑混在一起,后续难维护
新增 weknora_api.cjs 两套协议边界清晰,方便切换和回滚

3. 上传文件

把 IMA 的:

check_repeated_names → create_media → COS PUT → add_knowledge

替换为 WeKnora 的:

POST /api/v1/knowledge-bases/:id/knowledge/file

必要时保留本地前置检查,比如文件类型、大小、重名策略。

4. 添加 URL

把 IMA 的 import_urls 映射到 WeKnora 的:

POST /api/v1/knowledge-bases/:id/knowledge/url

WeKnora 后端会根据 URL 和参数判断是网页抓取还是远程文件模式。

5. 搜索知识

把 IMA 的 search_knowledge 映射到:

POST /api/v1/knowledge-search

这个接口更适合做"只要检索结果,不要大模型总结"的场景。

6. RAG 问答

如果用户表达是:

"根据知识库回答一下......"

那更适合走:

POST /api/v1/knowledge-chat/:session_id

因为它会完成检索 + 生成,并通过 SSE 流返回答案。

7. 响应归一化

建议内部统一成一种结构,比如:

统一字段 来源
code success=true 转成 0
msg 成功为 ok,失败取 error.message
data 透传 WeKnora 的业务数据

这样上层 Skill 就不用到处判断 successerror、SSE、HTTP 状态码。

哪些能力适合迁移?哪些先别动?

能力 是否建议迁移 原因
上传文件到知识库 建议 WeKnora 有明确文件上传接口
添加网页到知识库 建议 WeKnora 有 URL 创建知识接口
搜索知识库 建议 可映射 knowledge-search
RAG 问答 建议 可映射 knowledge-chat
查看知识库列表 可做 需要按 WeKnora KB API 重新实现
IMA notes 笔记 暂不建议 WeKnora 没有完全等价的个人笔记模型
IMA 云端鉴权 不迁移 WeKnora 有自己的鉴权和权限体系
IMA COS 上传链路 不迁移 WeKnora 上传协议不同

这道题相关的知识点

1. Agent Skill

Agent Skill 本质上是一组"给 Agent 看的操作规范"。它不只是函数库,还包含:

内容 作用
描述信息 告诉 Agent 什么时候该用这个 Skill
路由规则 告诉 Agent 用户意图应该进入哪个模块
API 模板 告诉 Agent 怎么构造请求
安全规则 比如文件类型限制、编码检查、敏感操作确认
脚本工具 真正执行 HTTP 请求、文件上传、解析响应

2. RAG

RAG 的完整名字是 Retrieval-Augmented Generation,检索增强生成。

它的核心不是让模型"背下资料",而是在回答前先检索资料,再基于资料生成答案。

3. BM25、向量检索和图谱检索

检索方式 擅长什么 不擅长什么
BM25 关键词精确匹配 同义词、语义变体
向量检索 语义相似 精确数字、专有名词有时不稳
图谱检索 实体关系、关联路径 构建成本更高

企业级 RAG 往往不会只押宝一种检索方式,而是多路召回后再重排序。

4. ReAct Agent

ReAct 可以简单理解成:

Reasoning + Acting,也就是边思考边行动。

它不是一次性回答,而是可能经历:

思考 → 调工具 → 看结果 → 再思考 → 再调工具 → 给最终回答。

WeKnora 的 Agent 模式就更接近这种多步推理链路。

5. Multipart 上传 vs 对象存储上传

上传方式 特点
multipart 直传 客户端把文件直接提交给业务后端
对象存储上传 后端先发临时凭证,客户端把文件传到 COS/S3/OSS,再回调登记

IMA 用的是更偏对象存储登记的流程;WeKnora API 文档展示的是更直接的 multipart 创建知识流程。

6. SSE 流式响应

SSE,全称 Server-Sent Events,是服务端持续向客户端推送消息的一种方式。

RAG 问答里常见的"字一个个冒出来"的效果,很多就是通过 SSE 或 WebSocket 实现的。

WeKnora 的 knowledge-chatagent-chat 文档都提到支持 SSE 流式响应。

7. 适配层 / 防腐层

当两个系统的数据结构和协议不一样时,不建议让业务代码到处写 if IMA else WeKnora

更好的方式是做一层 Adapter:

上层看到的 适配层负责的
上传知识 转成 WeKnora multipart 上传
搜索知识 转成 WeKnora knowledge-search
RAG 问答 转成 WeKnora knowledge-chat
统一响应 把 success/data/error 转成统一结构

这就是典型的防腐层思想:别让外部系统的复杂性污染上层业务语义。

最后总结

ima-skillsWeKnora 都和"知识库 + Agent"有关,但它们处在不同层级:

名称 更像什么
ima-skills Agent 操作 IMA 的技能说明书和工具包
WeKnora 企业知识 RAG、Agent、Wiki、权限、观测的一体化平台

所以,ima-skills 接入内网 WeKnora 的正确判断是:

语义层可以借鉴,接口层必须重写;不是改域名,而是做适配。

最推荐的方案是:

  1. 保留"上传文件、添加 URL、搜索知识库、RAG 问答"等用户意图。
  2. 新增 weknora_api.cjs,独立封装 WeKnora API。
  3. 用 WeKnora 的鉴权、上传、检索、问答接口替换 IMA 的底层链路。
  4. 做响应归一化,让上层 Agent 不感知底层差异。
  5. notes 这类 IMA 专属能力先不迁移,避免强行设计一个不存在的等价模型。

一句话收束:

ima-skills 像遥控器,WeKnora 像另一台功能更强的新电视。按钮习惯可以沿用,但红外协议得重新对上。

相关推荐
老云讲算力市场1 小时前
深圳奇点点信息科技有限公司连续中标多项AI算力项目
人工智能·科技
程序员天天困1 小时前
GPT-5.6 来了!三款模型、Ultra 模式、编程能力全面解析
人工智能·chatgpt
AIGS0011 小时前
向量空间JBoltAI:本体语义如何跨越企业AI的语义鸿沟
java·大数据·人工智能·人工智能ai大模型应用
Lucky_luckyZzz1 小时前
明略科技·灵听工牌深度测评:四位一体闭环如何落地门店销售管理?
人工智能
xiaotie10052 小时前
DeerFlow 2.0 Windows LocalSandbox Shell 执行 Bug 完整排查修复报告
人工智能
神奇小汤圆2 小时前
Loop Engineering 半年实战拆解 :自进化的开发系统已开源
人工智能
熊猫钓鱼>_>2 小时前
Electron:当 Web 技术统治桌面
大数据·前端·javascript·人工智能·架构·electron·agent
城事漫游Molly2 小时前
用AI提炼研究问题与假设的完整提示词——从模糊想法到精准RQ/Hypothesis,AI辅助精化全流程
人工智能·机器学习·prompt·ai for science·博士生必读·应用语言学·研究问题
AI刀刀2 小时前
豆包智能体对话导出后,如何构建长期归档与高效检索体系?
android·人工智能·word·excel·ai导出鸭