详情

首页手游攻略 从 ima-skills 到 WeKnora:Agent Skill 能否直接接入企业级 RAG?一次把原理讲清楚

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

佚名 2026-07-11 09:03:58

从 ima-skills 到 WeKnora

写在前面

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

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

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

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

ima-skills

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

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

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

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

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

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

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

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?

结论先说:不能直接接。

更准确一点:

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

差异一: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 的技能调用依赖:

系统鉴权方式
IMAClient 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 里,常见上传可以是这样:

# 通过 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 流

示例:

# 在指定 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 / IMAWeKnora适配建议
定位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 KeyX-API-Key、账号、RBAC重写鉴权层
上传create media + COS + add knowledgemultipart 上传知识删除 IMA 上传链路
返回结构{code,msg,data}{success,data,error} / SSE做响应归一化
部署形态依附 IMA 云服务和宿主 Agent可私有化部署内网部署更适合 WeKnora

一句话总结:

正确姿势:做一个 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 的直接等价模型

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

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

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

// 统一封装 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();}

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

// 把“搜索知识库”的 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 || [],};}

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

适配方案清单

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

1. 配置层

新增三个基础配置:

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

2. HTTP Client 层

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

原因很简单:

做法风险
直接改 ima_api.cjsIMA 与 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. 响应归一化

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

统一字段来源
codesuccess=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 可以简单理解成:

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

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

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-skillsAgent 操作 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 专属能力先不迁移,避免强行设计一个不存在的等价模型。

一句话收束:

相关资讯
点击查看更多
游戏推荐
推荐专题
热门阅读
推荐下载