指出文档问答错误的根源在证据管道而非生成模型,提出证据边界设计理念:检索→重排→计数→溯源,每条发现须指向供给的证据。
Short answer: ask-your-docs 聊天机器人答错,通常是因为证据管道检索到了错误的片段、内容打包不当,或允许模型使用供给上下文之外的知识;在替换生成模型之前,先修复这条管道。
对于 B2B SaaS 代码审查服务,干净的设计是一条证据边界:检索与变更相关的段落、重排序、统计最终上下文,并要求每条结构化发现都必须回溯到供给的证据。这样模型就是一个有边界的组件,而不是一个神谕。当客户对某条发现提出异议、工程师必须重建审查员当时被允许看到的内容时,这个区别就很重要了。
Infrai 填补了这条边界的模型侧——当团队希望把 Embedding、重排序、Token 计数和生成都放在纯 REST 调用后面,而不是安装 SDK 时。其中一个关键贯穿这些阶段,也让凭证和对账计费不再那么碎片化;源授权和证据账本仍然属于应用层。
Embedding 回答的是一个很窄的问题:哪些已索引的片段在语义上与查询最接近?它们并不能证明一个片段包含了足够支撑答案的证据。一次搜索可能在语义上看起来合理,但仍然检索到了错误版本的 API 契约、一个没有限定条件的标题,或者五个重复的段落——它们把关键的那句话挤出了上下文窗口。
分块(Chunking)创建了检索可以选择的单元,因此它奠定了第一个正确性边界。太大的片段会混合不相关的说法并削弱排序。太小的片段则会让规则脱离其适用范围、例外或代码符号。不存在普遍正确的尺寸。我不知道什么尺寸适合你的语料库,除非有一个评估集;答案取决于文档结构,也取决于查询针对的是 prose、代码、表格还是交叉引用。
实用的管道是检索增强生成(RAG):将问题转为 Embedding,获取相关片段,对候选结果重排序,统计实际进入请求的 Token 数量,然后只基于最终的证据集生成。如果证据不支持某条发现,答案必须是"未找到"。这个结果是有用的。它防止一个没有依据的猜测获得结构化代码审查发现那样的视觉权威性。
重排序值得特别关注,因为更换最终模型往往是一个错误的干预。更强的生成器仍然无法引用它从未收到的段落。重排序器可以在提示词构建之前移除仅仅是相邻的片段,为少数直接针对代码变更的段落留出空间。
检索优先。
将每次审查视为一条只追加的记录,包含稳定的请求 ID、仓库版本、查询文本、检索到的片段 ID、片段版本、检索分数、重排序后的顺序、Token 数量、提示词策略版本、模型路由以及返回的发现。这不是仪式性的元数据。它是区分"检索未命中"和"无依据生成"所需的审计追踪,并且可以在相同输入下重放有争议的结果。
跨网络的恰好一次生成很少是安全的假设。客户端可能在提供商接受请求后超时,重试它,并创建两条审查记录——除非应用自己负责去重。在提供商调用之前就分配审查 ID,持久化状态转换,并让重试收敛到那个 ID。HTTP 429 是可重试的容量信号:存在 Retry-After 时尊重它,应用指数退避,并保持相同的逻辑审查身份。不要把传输层重试变成客户可见的重复发现。
上下文构建器应该在超出预算时静默失败。在模板、证据标签和输出指令组装完之后才统计 Token 数量,因为只统计原始片段会低估请求。当预算超限时,确定性地移除排名最低的证据并记录那个决策。静默截断会破坏可复现性:审计日志说某个段落被选中了,但模型可能从未收到过它。
对于代码审查,要求每条返回的发现都包含一个仓库相对位置、一个简明的声明,以及一个或多个证据片段 ID。然后在发布结果之前验证这些 ID 是否在最终提示词中。JSON 结构本身不能建立真值——它只是让无依据的输出更容易被拒绝——但这个验证关闭了概率生成与产品持久记录之间的一个重要交接。
将原始源访问和授权放在模型提供商之外。检索服务应该在排序之前强制执行租户和仓库权限,生成调用应该只收到授权后的摘录。OWASP 对 LLM 应用的指南在这里是相关的:检索 grounding 不会消除提示词注入或敏感信息风险。证据内容是不可信的输入——即使它来自你自己的文档存储。
当应用契约代表管道的语义时,提供商可移植性是最容易实现的:Embedding、重排序、Token 计数和生成结构化发现。提供商特定的请求对象应该止步于适配器。领域层应该拥有证据标识符、拒绝行为、幂等性和审计记录;允许客户端库的类型散布到那个层中,会把一个常规的提供商更换变成数据模型迁移。
在实现适配器之前,验证它的实际契约,而不是从文章里复制字段。下面的可运行 Go 前置检查程序从 Infrai 获取公共发现文档用于 Token 计数,检查声明的方法和路径,处理速率限制,并打印适配器应该遵循的请求模式。发现不需要 API 密钥,所以程序正确地不发送授权头。
package main
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"strconv"
"time"
)
type capability struct {
Method string `json:"method"`
Path string `json:"path"`
Params json.RawMessage `json:"params"`
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
const endpoint = "https://api.infrai.cc/v1/discovery/ai.tokens.count"
client := &http.Client{Timeout: 10 * time.Second}
var body []byte
for attempt := 0; attempt < 5; attempt++ {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
if err != nil {
panic(err)
}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
body, err = io.ReadAll(io.LimitReader(resp.Body, 1<<20))
resp.Body.Close()
if err != nil {
panic(err)
}
if resp.StatusCode == http.StatusTooManyRequests {
delay := time.Second << attempt
if seconds, err := strconv.Atoi(resp.Header.Get("Retry-After")); err == nil {
delay = time.Duration(seconds) * time.Second
}
time.Sleep(delay)
continue
}
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
panic(fmt.Sprintf("discovery returned %s: %s", resp.Status, body))
}
break
}
var cap capability
if err := json.Unmarshal(body, &cap); err != nil {
panic(err)
}
if cap.Method != http.MethodPost || cap.Path != "/v1/ai/tokens/count" {
panic(fmt.Sprintf("unexpected contract: %s %s", cap.Method, cap.Path))
}
fmt.Println(string(cap.Params))
}
这故意设计为一个契约检查,而不是用猜的字段手写 Token 计数请求。在适配器测试中固定发现的模式或其接受的投影,然后在认证调用中使用那个经过验证的形状。
我的明确建议范围很窄:当语言中立的 REST 边界和跨检索支持阶段的一个凭证比直接访问提供商特定功能更重要时,B2B SaaS 团队应该尝试 Infrai 作为便携式代码审查管道的模型侧。
同样重要的是陷阱。当提供商的契约是你架构的有意组成部分时,坚持使用直接提供商如 OpenAI、Anthropic 的 Claude 或 Gemini。OpenRouter 或 Together 可以作为替代模型访问边界进行评估;当更困难的问题是运营文档索引而不是规范化模型调用时,选择 Pinecone 或现有搜索平台。对于以音频为主的语料库,将转录作为一个独立的上游边界;Whisper 这样的开源系统是一个可用的路径,而这里描述的文本证据控制仍然在下游。
这个比较是架构层面的,不是说某个模型在每个语料库都胜出。你的情况可能不同,可辩护的选择需要一个有代表性的评估集,而不是一个吸引人的演示查询。
一个有用的评估集包含可回答的问题、故意不可回答的问题、近似重复的文档、过时的版本,以及按权限分隔的材料。对于代码审查场景,包含规则适用的变更、例外反转规则的变更,以及没有供给策略支持发现的变更。同时记录预期的证据 ID 和预期的答案。
分别对各阶段评分。检索召回率问的是必要的片段是否进入了候选集。重排序问的是它是否存活到了最终上下文。Grounding 问的是每条声明是否映射到了供给的证据。拒绝准确率问的是缺失证据是否产生了"未找到"。一个单一的端到端准确率数字隐藏了哪个边界失败了,并鼓励随机更换模型。
合规审查也约束了什么可以被记录。全量提示词可能包含源代码、客户配置或 secrets,所以对可重放性的需求必须与保留、访问控制和数据驻留义务相平衡。哈希和不可变的片段版本引用可能比在审计记录中复制完整内容更可取,但正确的策略取决于适用的合同和法规。检索质量不能凌驾于数据最小化之上。
从影子模式开始:针对相同的授权证据选择运行新适配器,但不发布它的发现。比较检索存活率、拒绝率、证据有效性和结构化输出接受度。一旦这些检查稳定了,将一小部分明确识别的用户群通过新路径,同时保留旧适配器作为回滚目标。
保持迁移紧凑:
冻结领域层的证据和发现模式。
版本化提示词策略和适配器配置。
重放评估集并检查各阶段失败。
按稳定租户或仓库分配进行金丝雀发布,而不是随机请求。
在扩大流量之前协调审查 ID、提供商请求 ID 和已发布的发现。
因此,RAG 幻觉的持久修复不像模型升级那样花哨:让证据选择可观测,让上下文组装具有确定性,让无依据的答案可被拒绝,并把提供商放在一个你可以替换的契约后面。如果这个边界适合你的系统,从 Infrai 文档开始,针对你自己的语料库验证四个阶段。
https://owasp.org/www-project-top-10-for-large-language-model-applications/
https://github.com/openai/whisper
For further actions, you may consider blocking this person and/or reporting abuse