From fa938ca1ebfb61d407d7c7aa1691fe91918fd4bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A7=9A=E7=AB=A0=E6=B5=A9?= Date: Thu, 10 Sep 2026 16:59:22 +0800 Subject: [PATCH] docs: translate documentation and environment comments to Chinese --- .env.example | 50 ++++++++------------ docs/api-gaps.md | 32 ++++++------- docs/architecture.md | 108 +++++++++++++++++++++++-------------------- 3 files changed, 94 insertions(+), 96 deletions(-) diff --git a/.env.example b/.env.example index e8878f2..45ec6eb 100644 --- a/.env.example +++ b/.env.example @@ -1,62 +1,52 @@ -# DobotAI configuration +# DobotAI 基础配置 DOBOTAI_LISTEN_ADDR=127.0.0.1:8090 DOBOTAI_INGRESS_TOKEN=replace-me -# Optional local-only audit API. Use a distinct secret from DOBOTAI_INGRESS_TOKEN. -# When set, DOBOTAI_TENANT_KEY must be set and the listen address must be loopback-only. +# 可选的仅本机审计 API。必须使用不同于 DOBOTAI_INGRESS_TOKEN 的独立密钥。 +# 设置后必须同时设置 DOBOTAI_TENANT_KEY,且监听地址必须仅为回环地址。 DOBOTAI_ADMIN_TOKEN= DOBOTAI_GROUP_SESSION_POLICY=shared DOBOTAI_AGENT_BINDINGS={"dingtalk:*":"replace-with-agent-id"} -# Required for /think routing. The base binding above remains the stable -# Session identity; these select the execution Agent for each Turn. +# `/think` 路由必填。上面的基础绑定保持稳定的会话身份;以下配置仅选择每个 Turn 的执行 Agent。 DOBOTAI_QUICK_AGENT_ID=builtin-quick-answer DOBOTAI_REASONING_AGENT_ID=builtin-smart-reasoning -# Official WeKnora API only +# 仅使用 WeKnora 官方 API WEKNORA_BASE_URL=http://127.0.0.1:8080 WEKNORA_API_KEY=replace-me -# DingTalk Stream mode (official SDK). Leave all three empty to disable the -# DingTalk channel; set all three to enable it. Never commit real values. +# 钉钉 Stream 模式(官方 SDK)。三项均留空时禁用钉钉渠道;三项同时设置时启用。不得提交真实值。 DINGTALK_CLIENT_ID= DINGTALK_CLIENT_SECRET= -# Tenant key this DingTalk ingress serves (matches tenant_key used by QA). +# 该钉钉接入服务的租户键(必须与 QA 使用的 tenant_key 一致)。 DOBOTAI_TENANT_KEY= -# Optional DingTalk AI card template ID. Leave empty to use markdown-only replies. -# When set, a successful QA answer will be delivered as an AI card; markdown -# is only sent as a fallback when card delivery fails. Never commit real values. +# 可选的钉钉 AI 卡片模板 ID。留空时仅使用 Markdown 回复。 +# 设置后,成功的 QA 回答优先通过 AI 卡片发送;仅当卡片发送失败时才回退 Markdown。不得提交真实值。 DINGTALK_CARD_TEMPLATE_ID= -# Optional, temporary DingTalk card-debug allowlist. When set, only this exact -# DingTalk user receives _CARD_DEBUG_TOOL_ENTRY=show in per-user privateData. -# Keep empty outside a controlled debug session; never commit a real user ID. +# 可选、临时的钉钉卡片调试白名单。设置后,只有该指定钉钉用户会在 per-user privateData 中收到 _CARD_DEBUG_TOOL_ENTRY=show。 +# 非受控调试期间必须留空;不得提交真实用户 ID。 DINGTALK_CARD_DEBUG_USER_ID= -# Optional DingTalk FAQ table workflow for uncovered questions. Set all four -# values together; leave all four empty to disable. Required when the support -# group notification below is enabled. Never commit real IDs. +# 可选的钉钉 FAQ 表工作流,用于未覆盖问题。四项必须同时设置;四项均留空时禁用。 +# 启用下方人工支持群通知时,此工作流为必需项。不得提交真实 ID。 DINGTALK_FAQ_TABLE_BASE_ID= DINGTALK_FAQ_TABLE_SHEET_ID= DINGTALK_FAQ_TABLE_VIEW_ID= DINGTALK_FAQ_TABLE_OPERATOR_ID= -# Optional PDF-answer image egress for DingTalk cards. When any value is set, -# all five values are required. DobotAI downloads only authenticated resource:// -# images from WEKNORA_BASE_URL /files, writes content-hashed copies under -# dobotai/im-images/, and emits private OSS GET URLs valid for 2 hours. -# Keep the bucket private and configure an OSS lifecycle rule to delete -# dobotai/im-images/ objects after 1 day. Never commit real credentials. +# 可选的钉钉卡片回答图片外发。任一项设置后,以下五项都必须设置。 +# DobotAI 仅从 WEKNORA_BASE_URL 的 /files 鉴权下载 resource:// 图片,在 dobotai/im-images/ 下写入内容哈希副本,并生成有效期2小时的私有 OSS GET URL。 +# Bucket 必须保持私有,并配置 OSS 生命周期规则,在1天后删除 dobotai/im-images/ 对象。不得提交真实凭据。 DOBOTAI_OUTBOUND_IMAGE_OSS_ENDPOINT= DOBOTAI_OUTBOUND_IMAGE_OSS_REGION= DOBOTAI_OUTBOUND_IMAGE_OSS_ACCESS_KEY_ID= DOBOTAI_OUTBOUND_IMAGE_OSS_ACCESS_KEY_SECRET= DOBOTAI_OUTBOUND_IMAGE_OSS_BUCKET= -# Optional support group for uncovered-answer notifications. This is the -# group's openConversationId, not a webhook. Leave empty to record coverage -# decisions and pending support cases without sending group notifications. -# When enabled, the FAQ table workflow above must also be configured so the -# ActionCard can link to the exact FAQ record. Never commit a real group ID. +# 可选的未覆盖回答人工支持群通知。该值是群的 openConversationId,不是 webhook。 +# 留空时仍记录覆盖判定和待处理 Support Case,但不发送群通知。 +# 启用后必须同时配置上方 FAQ 表工作流,使 ActionCard 能链接到准确的 FAQ 记录。不得提交真实群 ID。 DINGTALK_SUPPORT_GROUP_OPEN_CONVERSATION_ID= -# Independent DobotAI PostgreSQL; never point this at WeKnora's database +# 独立的 DobotAI PostgreSQL;不得指向 WeKnora 数据库 DATABASE_URL=postgres://dobotai:replace-me@127.0.0.1:5432/dobotai?sslmode=disable diff --git a/docs/api-gaps.md b/docs/api-gaps.md index dba2064..72da9ae 100644 --- a/docs/api-gaps.md +++ b/docs/api-gaps.md @@ -1,21 +1,21 @@ -# WeKnora API Capability Gaps +# WeKnora API 能力缺口 -These gaps must not be solved with private WeKnora source or database changes. +以下能力缺口不得通过修改 WeKnora 私有源码或数据库解决。 -| Capability | Current external handling | +| 能力 | 当前外部处理方式 | |---|---| -| Like/dislike and unresolved reason | DobotAI PostgreSQL and API | -| Formal covered/not-covered decision | DobotAI evaluation rules using references, scores, answer status, and offline calibration | -| Support case, owner, SLA, and status | DobotAI workflow | -| Human reply to original channel | DobotAI channel adapter; not written to WeKnora history by default | -| Stable external turn correlation | DobotAI mapping of external message, turn, WeKnora session/request, and gateway trace | -| Complete multi-call token usage | Model gateway/Langfuse; unknown remains null/unknown | -| Strict image failure semantics | Adapter contract test; reject image traffic on failure | -| Arbitrary human assistant-message append | Keep in DobotAI and submit an upstream API request only if context injection becomes necessary | +| 点赞、点踩和未解决原因 | DobotAI PostgreSQL 与 API | +| 正式的已覆盖/未覆盖判定 | DobotAI 基于引用、分数、回答状态和离线校准的评估规则 | +| Support Case、负责人、SLA 和状态 | DobotAI 工作流 | +| 向原始渠道发送人工回复 | DobotAI 渠道适配器;默认不写回 WeKnora 历史 | +| 稳定的外部 Turn 关联 | DobotAI 映射外部消息、Turn、WeKnora 会话/请求和网关追踪 | +| 完整的多调用 Token 用量 | 模型网关/Langfuse;未知值保持 `null/unknown` | +| 严格的图片失败语义 | Adapter 契约测试;图片流量失败时拒绝处理 | +| 任意人工助手消息追加 | 保留在 DobotAI;仅当确有上下文注入需求时向上游提交 API 请求 | -Allowed responses to a gap: +面对能力缺口时,只允许: -1. adjust the product design; -2. implement it outside WeKnora; -3. open an upstream issue; -4. submit a general upstream pull request. +1. 调整产品设计; +2. 在 WeKnora 外部实现; +3. 提交上游 Issue; +4. 提交通用的上游 Pull Request。 \ No newline at end of file diff --git a/docs/architecture.md b/docs/architecture.md index 73bc974..b8ebdc2 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,74 +1,82 @@ -# DobotAI External Architecture +# DobotAI 外部集成架构 -## Boundary +## 系统边界 ```text -DingTalk / WeCom / Web / Software - -> DobotAI ingress and workflows +钉钉 / 企业微信 / Web / 业务软件 + -> DobotAI 接入层与工作流 -> WeKnora Adapter - -> official WeKnora REST API - -> official WeKnora RAG and Agent + -> WeKnora 官方 REST API + -> WeKnora 官方 RAG 与 Agent ``` -DobotAI PostgreSQL owns channel identities, external messages, session mappings, turns, feedback, coverage decisions, support cases, human replies, FAQ workflow state, and content-source mappings. WeKnora owns only its official data model. +DobotAI PostgreSQL 负责渠道身份、外部消息、会话映射、Turn、反馈、覆盖判定、Support Case、人工回复、FAQ 工作流状态和内容源映射。WeKnora 仅负责其官方数据模型。 -## Session policy +## 会话策略 -Default policy: +默认策略: -- direct: one long-lived session per tenant + channel + Agent + external user; -- group: one shared session per tenant + channel + Agent + external group; -- group messages are admitted only when the bot is mentioned or an explicit command triggers it; -- sender display name is prefixed to the query so a shared Agent can distinguish speakers; -- future controls must include idle rotation and an explicit new-conversation command; -- confidential channels may switch to `per_user`, yielding group + user sessions. +- 私聊:每个 `tenant + channel + Agent + 外部用户` 使用一个长期会话; +- 群聊:每个 `tenant + channel + Agent + 外部群` 使用一个共享会话; +- 群消息仅在机器人被提及或命中显式命令时进入处理; +- 将发送人显示名添加到问题前缀,使共享 Agent 能区分发言者; +- 后续控制项必须包含空闲轮换和显式新建会话命令; +- 保密渠道可切换为 `per_user`,形成群组加用户维度的会话。 -Shared group sessions are the common collaboration-bot pattern because all members see the same conversation. Group+user sessions provide stronger context isolation but make replies less coherent for collaborative group discussions. +共享群会话符合协作机器人场景:所有成员能看到相同上下文。群组加用户会话能增强上下文隔离,但会削弱协作讨论中的回复连贯性。 -## Agent binding +快速问答与智能推理必须复用同一个 WeKnora Session;`/think` 仅改变当前 Turn 的执行 Agent,不得重建会话映射。 -Agents are configuration-owned. Channel callers cannot choose an arbitrary `agent_id`. +## Agent 绑定 -Resolution order: +Agent 由配置控制,渠道调用方不得任意指定 `agent_id`。 -1. exact `:` binding; -2. channel wildcard `:*`; -3. fail closed when no binding exists. +解析顺序: -## Image failure policy +1. 精确 `:` 绑定; +2. 渠道通配 `:*`; +3. 没有任何绑定时失败关闭。 -Before enabling image traffic, the WeKnora Adapter must run a contract test against the selected official release and configured vision model. +## 图片失败策略 -If any image path fails: +启用图片流量前,WeKnora Adapter 必须针对选定的官方版本和视觉模型执行契约测试。 -1. do not resend the question without the image; -2. do not return partial model output as success; -3. return a typed `vision_unavailable` failure to the channel adapter; -4. DingTalk tells the user that image recognition is temporarily unavailable and asks them to retry or send text; -5. emit an operational alert to verify Agent image upload settings, selected vision model, provider connectivity, and model capability; -6. keep image traffic disabled until the contract test passes. +任一图片路径失败时: -No WeKnora source patch is allowed as a workaround. +1. 不得去掉图片后重发同一问题; +2. 不得将部分模型输出当作成功结果; +3. 向渠道适配器返回类型化 `vision_unavailable` 错误; +4. 钉钉提示用户图片识别暂不可用,并请其重试或发送文本; +5. 发送运维告警,核查 Agent 图片上传设置、视觉模型、供应商连通性和模型能力; +6. 契约测试通过前保持图片流量禁用。 -## Service ownership +不得通过修改 WeKnora 源码规避上述失败。 -- `internal/weknora`: official REST/SSE compatibility only. -- `internal/qa`: business orchestration and terminal-state ownership. -- `internal/session`: external-to-WeKnora session policy. -- `internal/store/postgres`: DobotAI business persistence only. -- `internal/coverage`: v1 covered/uncovered evaluation, durable support-case dispatch, finite retries, and stable failure codes. Notification failures never change a successful QA result. -- `internal/channels/dingtalk`: DingTalk Stream ingress (official SDK), text-only robot callbacks, fail-closed session webhook replies (`https`, `*.dingtalk.com`, no redirects). Wired in `cmd/dobotai`; enabled only when `DINGTALK_CLIENT_ID`, `DINGTALK_CLIENT_SECRET`, and `DOBOTAI_TENANT_KEY` are all set. Group messages require an @-mention; direct chats map to one long-lived session per user, groups to one shared session per group. Images, OpenAPI fallback, and card replies are not implemented yet. -- future `channels/*`: platform callbacks and outbound replies. -- future `content-sync/*`: DingTalk KB, NAS, and CMS synchronization. -- model gateway: token accounting, routing, quotas, circuit breaking, and provider observability. -- Redis: queue, retry, short leases, and temporary stream state only. +对钉钉 richText 中的图片,DobotAI 仅通过官方接口下载,验证来源、大小、媒体类型和文件签名后,才转换为 WeKnora 通用多模态请求。对回答中的 `resource://` 图片,仅可在鉴权获取、内容哈希转存私有 OSS 后外发;不得把任意外部 URL 当作可信图片。 -## Upgrade contract +## 服务职责 -For every official WeKnora upgrade: +- `internal/weknora`:仅处理 WeKnora 官方 REST/SSE 兼容;解析普通引用和智能推理工具结果引用; +- `internal/qa`:业务编排与 Turn 终态归属; +- `internal/session`:外部渠道到 WeKnora 的会话策略; +- `internal/store/postgres`:仅保存 DobotAI 业务数据; +- `internal/coverage`:已覆盖/未覆盖/纯视觉识别判定、持久化 Support Case、有限重试和稳定错误码;通知失败不得改变成功问答的结果; +- `internal/channels/dingtalk`:钉钉 Stream 接入、richText 与多图片归一化、AI 流式卡片、命令路由、反馈与通知。仅在 `DINGTALK_CLIENT_ID`、`DINGTALK_CLIENT_SECRET` 和 `DOBOTAI_TENANT_KEY` 均已设置时启用。群聊必须 `@` 机器人;私聊按用户映射长期会话,群聊默认映射共享会话;`sessionWebhook` 必须是 `https`、`*.dingtalk.com`、443端口且不允许重定向; +- `internal/reasoningmode`:`/think` 单次与持续推理、轮数、空闲到期、提示和首次使用引导; +- `internal/outboundimage`:WeKnora `resource://` 图片的受控鉴权下载和私有 OSS 外发; +- `future channels/*`:其他平台的回调与外发回复; +- `future content-sync/*`:钉钉知识库、NAS 与 CMS 同步; +- 模型网关:Token 统计、路由、配额、熔断和供应商可观测性; +- Redis:仅用于队列、重试、短期租约和临时流状态。 -1. update the pinned official release/tag; -2. run official database migrations against WeKnora only; -3. run DobotAI Adapter contract tests; -4. verify text Agent Chat, references, terminal errors, Stop, images, ingestion, and FAQ; -5. promote the official image only after the contract suite passes. +## 升级契约 + +每次升级官方 WeKnora 时: + +1. 更新固定的官方 Release/Tag; +2. 仅对 WeKnora 执行官方数据库迁移; +3. 执行 DobotAI Adapter 契约测试; +4. 验证文本 Agent Chat、引用、终止错误、停止、图片、导入和 FAQ; +5. 仅在契约测试通过后推广官方镜像。 + +WeKnora 升级、DobotAI 迁移、钉钉单消费者切换和生产部署是独立变更边界,必须各自备份、演练和验收。 \ No newline at end of file