企业知识库接入文档
资料只维护一份,问答入口按需打开。这份文档讲清楚每个入口怎么接:哪些点几下就好,哪些需要你们的开发同事写一点代码,以及每个入口能看到哪些库。
选一种接入方式
几种方式可以同时用,背后都是同一批知识库。先看看你们的同事平时在哪里干活:
| 入口 | 适合谁 | 要不要写代码 | 能问到哪些库 |
|---|---|---|---|
| TelosWork 客户端 | 每天用 AI 干活的员工 | 不用 | 提问人自己有权限的库 |
| 飞书 / 企业微信 / 钉钉 | 不装客户端的一线同事 | 不用,扫码或填凭证 | 数字员工绑定的库 |
| 对外 MCP 服务 | Claude、Cursor、Dify、n8n、自研智能体 | 不用,粘贴一段配置 | 端点开放的库 |
| 嵌入业务系统网页 即将上线 | 在 OA、ERP、CRM 里办事的员工 | 前端一段、后端一个小接口 | 数字员工绑定的库 |
准备工作
- 开通企业版与知识库资格。组织管理员在管理后台的「访问资格」里,给需要用企业知识库的成员开通资格;要创建企业数字员工的人,还需要在「创建企业员工」里单独授权。
- 建库、导入资料。在 TelosWork 的「知识库」页切到「企业」,按部门或主题建库,批量上传 PDF、Word、Excel、PPT、扫描件等文件,等待解析完成。
- 设置权限。给每个库按部门或成员分配查看、编辑、审核、管理权限。后面所有对外入口,都要求操作人是对应库的管理员。
- 确认你的知识库地址。用云端时由我们提供;部署在你们服务器时,就是部署时配置的域名(例如
https://kb.你们公司.com)。下文的<知识库地址>都指它。
在 TelosWork 里用
员工登录 TelosWork 客户端后,就能看到自己有权限的企业知识库,不需要额外配置。
- 在对话输入框里输入 @,选「知识库」,勾选要查的企业知识库,再提问。
- 或者在新对话里选一个企业数字员工,直接用它绑定的库回答。
- 回答里的角标 1 点开就是原文段落;可以接着让它把结果整理成表格、文档或 PPT。
客户端里的检索按提问人本人的权限进行:同一个问题,销售和财务看到的引用可能不同,没有权限的资料不会出现在回答里。
企业数字员工
数字员工是给知识库配的一个「岗位」:有名字、人设、欢迎语和绑定的知识库。IM 机器人和网页嵌入都挂在数字员工上,所以先建好它。
- 新建员工。在「数字员工」页切到「企业员工」,点新建,填写名称、图标,选择要绑定的知识库(需要这些库的管理员权限)。
- 写角色提示词。说清楚它是谁、回答风格、什么问题不回答。例如「你是远帆科技的制度助手,只回答人事、财务、行政制度问题,回答要引用制度原文」。
- 设欢迎语。员工第一次打开对话时看到的话,可以列几个常见问题作为引导。
- 分发设置。选择哪些部门或成员能在自己的 TelosWork 里用它。
- 打开对外入口。在「IM 机器人」页签挂到飞书、企业微信、钉钉;网页嵌入上线后在「网页嵌入」页签开通。
飞书 · 企业微信 · 钉钉
在企业员工的「查看配置 → IM 机器人」里点「管理机器人」,选平台后按下面的步骤操作。企业微信和钉钉支持扫码自动配置,会自动创建应用并校验凭证,推荐优先使用。只想给某几个库配一个独立问答机器人,也可以在企业知识库列表的「知识库问答机器人」里创建。
飞书
- 在飞书开放平台创建企业自建应用,在「凭证与基础信息」中复制 App ID 和 App Secret,填回 TelosWork。
- 在「添加应用能力」中启用机器人能力。
- 在「权限管理」中开通:
im:message.p2p_msg:readonly、im:message:send_as_bot、cardkit:card:write。 - 在「事件与回调」中把接收方式设为长连接,添加事件
im.message.receive_v1。需要首次私聊时自动发欢迎语的,再开通im:chat.access_event.bot_p2p_chat:read并订阅对应的进入会话事件。 - 在「版本管理与发布」中创建版本并发布,并把可用范围设为全员或指定部门。
企业微信
- 推荐:在 TelosWork 里点「扫码自动配置」,用企业微信扫码授权,自动创建智能机器人并填好凭证。
- 手动方式:企业微信客户端打开「工作台 → 智能机器人 → 创建机器人 → 手动创建」,选择 API 模式;在「API 配置」中把连接方式选为「使用长连接」,复制 Bot ID 与 Secret(Secret 只显示一次)。
- 设置机器人的可见范围。想在问答记录里看到提问人姓名,可以另填企业 ID 和一个有通讯录读权限的应用 Secret(选填)。
钉钉
- 推荐:在 TelosWork 里点「扫码自动配置」,用钉钉 App 扫码,自动创建内部应用并校验凭证。
- 手动方式:在钉钉开发者后台创建企业内部应用,复制 Client ID 和 Client Secret;在「机器人与消息推送」中开启机器人,消息接收模式选 Stream 模式。
- 想要打字机式的逐字回复,在钉钉卡片平台建一个 AI 卡片模板,把模板 ID 填进 TelosWork,并开通界面上列出的卡片权限;不填则回答生成完整段发出。
- 在「版本管理与发布」中发布新版本并设置可见范围。钉钉后台的任何修改都要发布新版本才生效。
对外 MCP 服务
把选定的知识库开放成一个标准 MCP 服务,任何支持 MCP 的 AI 工具或你们自研的智能体都能检索它。
- 在「知识库」页切到「企业」,打开「对外 MCP 服务」,点「新建」,填名称并勾选要开放的库。
- 在端点详情的「接入与密钥」页点「新建密钥」,填名称和有效期,点「创建并复制」。密钥只显示这一次,复制到剪贴板的就是完整配置。
- 粘贴到你的 MCP 客户端。标准格式如下:
{
"mcpServers": {
"telos-kb": {
"type": "http",
"url": "https://<知识库地址>/api/v1/kb-mcp/<端点 ID>",
"headers": { "Authorization": "Bearer <你的密钥>" }
}
}
}Dify、n8n 这类填表的平台,只需要填服务地址和请求头 Authorization: Bearer <你的密钥>。在详情页的「调用记录」里能看到每次调用的时间、结果和耗时;密钥可以随时吊销,端点可以随时停用。
嵌入业务系统网页 即将上线
在你们自己的 OA、ERP、CRM 网页右下角加一个问答按钮,员工登录你们的系统后点开就能问,不需要再登录 TelosWork。窗口可以浮在页面上,也可以在右侧占位、把页面内容往左挤。
接入一共三件事:管理员在 TelosWork 里开通(7.2);前端加一段代码(7.3);后端加一个签名接口(7.4)。
7.1它是怎么认人的
挂件自己不做登录,它相信你们系统的登录结果。你们的后端用一把只有双方知道的密钥签一张 5 分钟有效、只能用一次的「通行证」,挂件拿着它来换对话权限:
- 点开问答按钮,挂件请求你们的
/api/telos-widget-token - 检查登录状态,用密钥签一张 5 分钟通行证
- 挂件把通行证交给知识库,验签通过后开始对话
- 每次提问再检查:挂件是否启用、库是否还在、范围是否变化
所以:没登录你们系统的人用不了;能问到哪些库由数字员工绑定的库决定,所有登录用户看到的范围相同;每个人的对话历史互相隔离。
7.2在 TelosWork 开通
- 打开企业员工的「网页嵌入」页签,点「开通网页嵌入」。开通后默认是关闭状态,配置完再打开。
- 允许嵌入的网站:填你们系统的地址,例如
https://oa.yuanfan.com,必须是 https;子域名可以写https://*.yuanfan.com。不在列表里的网站加载不出挂件。 - 展开方式与外观:浮动或右侧占位、默认宽度、浅色或深色。
- 新建签名密钥:填名称和有效期,点「创建并复制」。会复制密钥 ID 和密钥,只显示这一次。同一个挂件最多两把有效密钥,用来轮换。
- 把「挂件 ID、密钥 ID、密钥」交给你们的开发同事,配进后端(见 7.4),然后打开开关。
7.3前端加一段代码
在你们系统的公共页面模板里,</body> 之前加入:
<script src="https://<知识库地址>/widget/loader.js"></script> <script> TelosWidget.init({ widgetId: 'wgt_7f3a9c2e41b8', // 换成你的挂件 ID mode: 'overlay', // overlay 浮在页面上;push 右侧占位、页面左移 getToken: async () => { const r = await fetch('/api/telos-widget-token', { credentials: 'same-origin', cache: 'no-store' }) if (r.status === 401) return null // 没登录:挂件显示「请先登录」 if (!r.ok) throw new Error('获取通行证失败') return (await r.json()).token }, }) </script>
| 参数 / 方法 | 说明 |
|---|---|
widgetId | 必填,在「网页嵌入」页签复制 |
getToken | 必填,返回通行证字符串;未登录返回 null。挂件会在需要时再次调用,不要自己缓存通行证 |
mode | overlay(默认)或 push;屏幕窄于 768px 时自动全屏 |
pushTarget | push 模式下被挤开的元素,默认整个页面;页面有固定定位的顶栏时可以指定主内容容器 |
onLayoutChange(width) | 窗口打开、关闭或拖动宽度时回调,方便你们调整自己的布局 |
TelosWidget.open() / close() / destroy() | 用自己的按钮控制打开、关闭;退出登录时调用 destroy() 清掉当前对话 |
7.4后端加签名接口
这个接口只做一件事:确认当前请求的用户已经登录,然后返回一张通行证。已登录返回 200 {"token":"..."},未登录返回 401,两种响应都带 Cache-Control: no-store。
Java 项目推荐直接用我们的 SDK,签名、有效期、一次性编号、禁止缓存和未登录处理都由它完成。你们只需要写一个方法,告诉它当前用户是谁。SDK 兼容 Java 8 及以上、Spring Boot 2.2+ 与 3.x,同一个 jar 包通用。
<!-- pom.xml --> <dependency> <groupId>com.shtelos.telos</groupId> <artifactId>telos-widget-spring-boot-starter</artifactId> <version>0.1.0</version> </dependency> # application.yml(三个值都从环境变量或配置中心读) telos: widget: widget-id: ${TELOS_WIDGET_ID} key-id: ${TELOS_WIDGET_KEY_ID} secret: ${TELOS_WIDGET_SECRET} # path: /api/telos-widget-token 默认就是这个地址 // 唯一要写的代码:告诉 SDK 当前登录用户是谁(以 Spring Security 为例) @Bean TelosWidgetUserResolver telosWidgetUserResolver() { return request -> { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth == null || !auth.isAuthenticated() || auth instanceof AnonymousAuthenticationToken) return null; // 未登录 → 401 LoginUser u = (LoginUser) auth.getPrincipal(); // 换成你们的用户类 return new TelosUser(String.valueOf(u.getId()), u.getRealName()); }; }
// 只依赖 telos-widget-core(零第三方依赖);Jakarta 项目把 javax.servlet 换成 jakarta.servlet public final class TelosWidgetTokenServlet extends HttpServlet { private final TelosWidgetSigner signer = TelosWidgetSigner.builder() .widgetId(System.getenv("TELOS_WIDGET_ID")) .keyId(System.getenv("TELOS_WIDGET_KEY_ID")) .secret(System.getenv("TELOS_WIDGET_SECRET")) .build(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.setHeader(TelosWidgetSigner.CACHE_CONTROL_HEADER, TelosWidgetSigner.CACHE_CONTROL_VALUE); LoginUser u = LoginContext.current(req); // 换成你们取当前登录用户的方法 if (u == null) { resp.setStatus(401); return; } resp.setContentType("application/json;charset=UTF-8"); resp.getWriter().write(signer.createTokenResponseJson(new TelosUser(u.getId(), u.getRealName()))); } }
// npm install jsonwebtoken import jwt from 'jsonwebtoken' import { randomUUID } from 'node:crypto' app.get('/api/telos-widget-token', (req, res) => { res.set('Cache-Control', 'no-store') const user = req.session?.user // 只从服务端登录态取 if (!user) return res.status(401).end() const token = jwt.sign( { sub: String(user.id), name: user.name, jti: randomUUID() }, process.env.TELOS_WIDGET_SECRET, { algorithm: 'HS256', audience: process.env.TELOS_WIDGET_ID, keyid: process.env.TELOS_WIDGET_KEY_ID, expiresIn: 300 }, ) res.json({ token }) })
# pip install pyjwt import os, time, uuid, jwt from flask import session, jsonify @app.get("/api/telos-widget-token") def telos_widget_token(): nocache = {"Cache-Control": "no-store"} user = session.get("user") # 只从服务端登录态取 if not user: return "", 401, nocache now = int(time.time()) token = jwt.encode( {"aud": os.environ["TELOS_WIDGET_ID"], "sub": str(user["id"]), "name": user["name"], "iat": now, "exp": now + 300, "jti": str(uuid.uuid4())}, os.environ["TELOS_WIDGET_SECRET"], algorithm="HS256", headers={"kid": os.environ["TELOS_WIDGET_KEY_ID"]}, ) return jsonify(token=token), 200, nocache
// go get github.com/golang-jwt/jwt/v5 github.com/google/uuid func telosWidgetToken(w http.ResponseWriter, r *http.Request) { w.Header().Set("Cache-Control", "no-store") user, ok := currentUser(r) // 只从服务端登录态取 if !ok { w.WriteHeader(http.StatusUnauthorized) return } now := time.Now() t := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "aud": os.Getenv("TELOS_WIDGET_ID"), "sub": user.ID, "name": user.Name, "iat": now.Unix(), "exp": now.Add(5 * time.Minute).Unix(), "jti": uuid.NewString(), }) t.Header["kid"] = os.Getenv("TELOS_WIDGET_KEY_ID") token, err := t.SignedString([]byte(os.Getenv("TELOS_WIDGET_SECRET"))) if err != nil { w.WriteHeader(http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{"token": token}) }
拿到 Java SDK
- 离线包:
telos-widget-java-sdk-0.1.0.zip,内含两个 jar、对应 pom 和安装脚本。解压后运行install.sh(Windows 用install.bat)装进本机 Maven 仓库,或把 jar 和 pom 上传到你们的 Nexus。开通网页嵌入时向我们索取。 - Maven 中央仓库:发布后这里会给出坐标,届时直接加依赖即可。
- .NET、PHP 等其他语言:任何标准 JWT 库都能按 7.5 的规范签发;需要示例可以联系我们。
用户 ID 怎么取
sub 用你们系统里稳定、不会复用的用户编号,例如用户表主键或工号,不要用手机号。name 选填,只用于问答记录里显示提问人。
7.5令牌规范
通行证是一个标准的 HS256 JWT。不用 SDK 的语言按下表签发即可;SDK 已经按它实现。
| 位置 | 字段 | 要求 |
|---|---|---|
| 头部 | alg / typ | 固定 HS256 / JWT,其他算法一律拒绝 |
| 头部 | kid | 密钥 ID,在「网页嵌入」页签复制 |
| 内容 | aud | 挂件 ID |
| 内容 | sub | 用户 ID,最长 128 个字符 |
| 内容 | name | 选填,显示名,最长 64 个字符 |
| 内容 | iat / exp | 签发、过期时间(秒级时间戳),exp 不超过 iat 之后 300 秒 |
| 内容 | jti | 随机 UUID,每张通行证不同,用过一次就作废 |
| 签名 | 密钥 | 把密钥字符串按 UTF-8 直接作为 HMAC 密钥,不做 Base64 解码 |
首期不读取其他字段,也不建议放入额外的个人信息。
7.6自测与排错
先在浏览器里登录你们的系统,打开 https://你们的系统/api/telos-widget-token:应该看到 {"token":"..."};退出登录后再打开应该是 401。响应头里要有 Cache-Control: no-store。
| 现象 | 常见原因 |
|---|---|
| 页面上没有出现问答按钮 | 网站地址不在「允许嵌入的网站」里;网页嵌入开关没打开;页面的内容安全策略拦截了知识库地址的脚本 |
| 点开后一直提示「请先登录」 | 签名接口返回了 401:检查接口能否读到你们的登录状态,以及请求是否带上了 Cookie |
| 提示「身份校验失败」 | 密钥或密钥 ID 不对、密钥已吊销或过期、挂件 ID 填错;复制密钥时多带了空格或换行 |
| 提示「通行证已过期」 | 你们服务器的时间不准,请开启时间同步;或者通行证被缓存了,确认接口每次都重新签发 |
| 能对话但回答「没有找到依据」 | 数字员工没有绑定库,或绑定的库里没有相关资料,去问答分析里看看具体问题 |
安全须知
- 每个对外入口都只能检索管理员为它开放的库;在 TelosWork 客户端里提问才按提问人本人的权限检索。
- MCP 密钥和网页嵌入的签名密钥创建时只显示一次,我们的界面、日志和接口都不会再返回明文。丢了就吊销重建。
- 网页嵌入的问答只回答问题、给出处,不提供原文件下载;对话按「挂件 + 用户」隔离,不同人之间看不到彼此的记录。
- 所有入口的问答都会进入问答分析,管理员可以按入口、员工、时间筛选查看。
- 任何入口都可以随时关闭:停用机器人、停用 MCP 端点、关闭网页嵌入,在途的对话会在下一次提问时失效。
常见问题
网页嵌入要多少开发量?
前端一段代码,后端一个接口。Java 项目引入 SDK 后只需写一个方法,告诉它当前登录用户是谁。
我们的系统不能改代码怎么办?
如果你们有统一身份认证(单点登录),可以和我们沟通对接方式;也可以先用飞书、企业微信、钉钉机器人,不需要改任何系统。
不同员工能看到不同范围吗?
机器人和网页嵌入目前对所有可用的人开放同一个范围。需要按人区分时,可以建多个数字员工分别绑定不同的库,或者让员工在 TelosWork 客户端里按本人权限提问。
部署在我们自己服务器上,接入方式一样吗?
一样,只是 <知识库地址> 换成你们的域名。内网环境用离线包安装 SDK,飞书、企业微信、钉钉机器人需要服务器能访问对应平台。