一句“帮我看看我基金组合”,怎样走过 ETF Agent 的六层系统

17 阅读55分钟

假设你买了几只名字各不相同的基金,想看看风险是否真的分散。基金数量增加了,底层投资对象却可能仍有重叠。你打开 ETF Agent,输入:

我的组合主要暴露在哪些行业?结合基金资料解释风险,缺少依据的部分请说明。

从用户看,这是一句问题,接下来应该是一份解释。从系统看,它会穿过身份、模型上下文、工具执行、证据处理、正文交付,以及持续观测。真正有趣的地方,是每一次“交给下一步”都改变了信息的用途:问题变成研究动作,工具结果变成模型材料,候选文字变成用户可见正文。

下面用这个合成场景带路,不对应真实持仓,也不表示所有故障曾在同一次运行连续发生。真实工程摩擦会在相应位置单独说明。图示简化职责与数据关系;观测贯穿全程,研究会多轮往返,普通问题也可能走直接回答的短路径。

全景图:一句问题穿过哪些交接

flowchart TD
    U["用户问题"]
    I["身份与入口决策"]
    P["Projector 装配请求"]
    M1["模型提出动作"]
    H["Host 获准执行"]
    E["材料读取与计算"]
    M2["结果回灌与继续推理"]
    A["正文发布与交付"]
    B["用户看到并继续追问"]
    O["观测关联各环节记录"]
    U --> I
    I --> P
    P --> M1
    M1 --> H
    H --> E
    E --> M2
    M2 --> A
    A --> B
    H -.-> O
    M2 -.-> O
    B -.-> O

这是需要工具的研究路径。结果回灌后,模型可以提出下一轮动作或提交答案;观测从各处取得独立记录,并非最后才开始。

层次接住的问题模块
第一层 · 交互与研究驱动先接住问题,再决定怎样走会话与请求身份、入口决策、原生研究循环
第二层 · 上下文与方法模型出发前,手里有什么统一 Projector、技能、个人背景与记忆
第三层 · 能力接入与执行一句“去查”,怎样成为事实模型网关、MCP 与 Host、生命周期钩子
第四层 · 证据与计算从找到材料,到形成可核对的判断知识检索、研究资产与文档阅读、确定性金融计算、隔离分析
第五层 · 交付与连续性答案来了,还要留得住、接得上答案发布、事件交付与前端、持久恢复与失败重试、多轮对话与任务接续
第六层 · 观测与评估让“发生了什么”和“答得怎样”各有依据Langfuse 观测、质量评估

第一层 · 交互与研究驱动:先接住问题,再决定怎样走

问题已经写好,用户按下发送。后台此时还没有组合结论,先要辨认这次提交、选择工作分支,再启动可以边研究边调整的执行过程。三个模块分别处理“这是谁的哪次发送”“需要什么工作”和“下一步怎样推进”。

这一层的必要性来自两个现实条件:网络会重复交付,研究路线又无法完全预排。把接入、语义路由和运行调度拆开,身份规则可以保持确定,研究策略可以随材料变化。我们引入研究循环的主要背景,是早期结构化回合让模型同时携带计划、状态和完成语义,维护负担与事实归属逐渐交织。

入口分支:重发、新问题与正文冲突

flowchart TD
    U["用户发送消息"]
    V["身份与消息一致性检查"]
    N["新消息身份"]
    R["相同身份与相同正文"]
    C["相同身份但正文冲突"]
    NR["建立新运行"]
    RR["查原运行并恢复或回放"]
    CR["拒绝覆盖已有执行"]
    U --> V
    V --> N
    V --> R
    V --> C
    N --> NR
    R --> RR
    C --> CR

消息身份把一次发送与实际运行关联起来。同一身份的重发查找原运行;正文冲突则拒绝,不覆盖已发生的执行。

研究驱动:模型选择行动,运行时留下事实

flowchart TD
    I["入口判断工作分支"]
    D["稳定解释:直接回答"]
    R["需要证据:进入研究"]
    M["模型提议下一步动作"]
    H["Host 执行并记录回执"]
    T["结果回灌当前请求"]
    M2["下一轮:补读或形成解释"]
    A["提交正文与必要缺口"]
    I --> D
    I --> R
    R --> M
    M --> H
    H --> T
    T --> M2
    M2 --> A
    D --> A

图中展开一轮研究。需要更多材料时进入下一轮;图中重复的模型节点用于表达前后两次推理,不是两个独立 Agent。

模块输入与产物为什么单独封装
会话与请求身份一次发送 → 可关联的消息和运行重发、回放与新任务需要明确区分
入口决策原问题与可用背景 → 工作分支问题理解可以独立于执行机制演进
研究循环模型动作与实际回执 → 下一轮或结束策略可变,执行记录仍需要稳定归属

01 会话与请求身份:发送两次,是否做了两次研究?

问题刚发出去,页面还没出现正文。设想网络此时抖动,用户又点了一次发送:后台收到的是第二道题,还是同一道题的重发?如果系统连这件事都认不清,后面的研究再聪明,也可能从重复工作开始。

用户按下发送按钮后,系统首先要建立请求身份。它需要确认消息属于哪个会话、由谁提交、允许访问什么资源,以及这次提交是不是上一次发送的重复。浏览器建立稳定的消息身份,服务端把消息关联到实际运行。这里的运行,是处理一次问题的执行实例,不是整段聊天记录的另一个名字。

会话负责交流关系,运行负责执行过程。同一个会话可以包含多个运行,保存用户原话和后续追问;每次运行则记录本轮模型调用、工具执行和答案交付。在示例里,最初的行业分析与后面的“那科技行业呢”可以共享会话背景,但它们不是同一份执行账本。这种区分让历史交流和实际动作各有归属。

稳定身份主要解决网络不确定性。浏览器没收到结果,并不能说明服务端没处理请求。如果每次重连都创建新任务,后台就可能重复调用模型、读取资料或生成答案。因此,同一消息重发时复用原身份;服务端查找既有运行,决定恢复还是回放。同一身份携带不同正文,则明确拒绝,不能悄悄覆盖已经发生的执行。

入口还会验证身份与资源范围。模型不能根据聊天内容授予账户权限,请求里出现一个会话标识也不能证明用户拥有它。访问资格必须在进入研究前由系统确认,而用户的问题含义留给模型解释。入口因此可以拒绝越权读取,却不会提前替用户设计完整分析方案。

因此,我们把会话身份、消息身份与运行身份分别管理,再通过关联关系连接起来。封装这一层,是为了让网页、后台任务和调查记录谈论同一次发送;它也让重连处理集中在入口,避免每个模型或工具适配器重新设计一套去重逻辑。代价是要维护身份关联与冲突处理,但这是系统可以明确核对的事实。

02 入口决策:先判断这道题需要哪种工作

终于进入系统了。模型面前的第一道选择,是要不要动用工具。用户若只问“行业集中是什么意思”,解释即可;现在问的是“我的组合”,还要求结合基金资料,答案就必须从一般知识走向具体证据。

不是每个问题都需要进入复杂研究。解释一个稳定概念、调整用户提供的文字,可能直接形成答案;分析当前组合、查询基金资料或执行计算,则需要工具。入口模型负责选择这条分支,它收到原问题、必要历史、参考目录和当前可用能力,提出直接回答或进入研究的决定。

这个选择依据任务所需的工作,而不是主题标签。“基金是什么”与“这只基金目前主要持有哪些行业”都属于金融问题,后者却需要当前来源。把所有金融问题机械路由到研究,会制造无用调用;全部直接回答,又容易让模型用一般知识替代具体产品事实。入口必须理解请求,程序则检查它提出的分支是否能够执行。

在贯穿示例中,入口应选择研究,因为用户要求读取个人组合并结合基金资料。它可以提出需要确认的问题,却不能声称已经看过组合,也不能把“允许请求某种能力”当成“已经取得相关数据”。入口阶段没有执行工具,研究计划只是一项语义提议。

混合问题更考验这一层。例如,组合数据不可用,但用户还要求解释行业集中为什么构成风险。独立的解释仍可能继续,不能因为一个部分阻塞就拒绝整道题。反过来,模型也不能用这段一般解释冒充对真实组合的分析。关键是保留完整请求,同时区分可以推进的部分和确实缺少条件的部分。

把入口决策单独封装,可以让直接问答保留一条短路径,也让研究任务带着完整问题进入后续循环。入口的变化主要围绕问题理解,研究运行时的变化主要围绕执行,两类演进因而有了各自的位置。我们接受一次额外决策的成本,换取明确的工作分支,同时持续检查错误路由是否来自指引或能力描述。

03 原生研究循环:答案在下一步行动中逐渐形成

研究开始后,第一份组合数据只是开头。假设分类里有“科技”,用户还会想知道它来自哪些基金、资料是否足够新。下一步可能是读取报告,也可能先核对分类。答案需要边走边形成,事先排一条固定搜索路线很难覆盖这些变化。

研究过程不是预先排好的固定流水线。模型读到组合数据后,可能需要进一步查看基金资料;发现资料口径不一致后,可能调整查询;得到足够支持后,开始组织答案。当前研究采用原生工具调用表达动作,运行时推动“模型提议—获准执行—结果回灌—继续推理”的循环。

模型负责选择研究策略,运行时负责记录与限制执行。工具是否真的调用、实际返回什么、动作是否取消或失败,都由代码和回执描述。模型可以判断某个研究问题已经解决,但这仍然是一项判断,不能直接变成“用户任务已经完成”的系统事实。这条边界贯穿普通研究和结束阶段。

早期探索中的一项重要摩擦,是让模型同时维护过多运行状态。提示里包含目标、计划、进度、缺口、动作和完成判断,结构越来越丰富,模型却需要在回答问题之外继续维护这些字段。计划容易与事实混在一起,恢复也必须解释模型生成的状态是否可信。

后来的方向,是让动作沿工具协议表达,让运行时保存真实执行记录。模型保留材料缺口、冲突和下一步研究问题,程序不要求它重新记账。一次读取成功,不再依赖模型在后续字段中准确重述;一次执行失败,也不会因为模型把问题标成解决而消失。

研究循环的封装把调度、取消、资源上限和执行记录放到同一生命周期中,让模型专注于下一步值得做什么。新增一项读取能力可以接入已有动作路径;系统不必为“先查组合再读报告”和“先读报告再核对组合”分别造流程。成本是运行时需要管理真实状态,但它减少了要求模型重复维护账本的负担。

到这里,问题获得了执行身份,也进入了需要读取证据的研究路径。下一步先看模型收到的材料包,再看它提出的动作如何被执行。

第二层 · 上下文与方法:模型出发前,手里有什么

让模型研究组合,并不意味着它已经看过组合。后台已有的材料、当前任务适用的方法和用户的表达偏好,要先组织成这一轮真正发送的输入。

这一层把“装配请求”“复用方法”和“跨会话背景”拆开,是因为它们分别面对容量、方法维护和生命周期问题。Projector 集中最终组装,技能保留领域差异,个人背景控制有限信息;长期记忆仍需要单独完成生产闭环。把三者统称为“增强上下文”,会掩盖材料究竟在哪一步进入,以及谁负责更新或撤回。

模型输入:多种材料在 Projector 收口

flowchart TD
    U["当前原问题与必要历史"]
    S["技能与有限个人背景"]
    T["工具转录与来源事实"]
    P["Projector:组织与拟合"]
    C["请求结构与工具面检查"]
    O["遗漏与投影观察"]
    G["网关提交实际请求"]
    U --> P
    S --> P
    T --> P
    P --> C
    P -.-> O
    C --> G

事实由原模块提供,投影器集中组织本轮模型视图。省略与容量处理需要留下记录;投影器不承担取数和授权。

背景分流:表达偏好、当前状态与长期记忆

flowchart TD
    P["有限稳定背景"]
    PP["当前获准背景投影"]
    C["当前组合状态"]
    CP["读取并核对当前来源"]
    M["本轮模型输入"]
    F["目标:长期记忆闭环"]
    FC["保存、纠正、遗忘回执"]
    FR["未来按范围与版本召回"]
    P --> PP
    C --> CP
    PP --> M
    CP --> M
    F -.-> FC
    FC -.-> FR

有限背景影响表达,当前组合沿权威读取取得。虚线表示长期记忆仍需完成的目标闭环,并不表示它已接入生产请求。

材料主要归属在故事中的用途
当前问题与实际工具结果上下文投影保留这一轮真正要答什么、已经读到什么
基金研究顺序与阅读方法技能提醒先核对产品、时间与限定条件
简洁表达等有限稳定背景个人背景调整解释方式
显式保存、纠正和遗忘的长期信息待完成的记忆闭环未来减少重复说明,并保留用户控制

04 统一 Projector:给模型装好这一轮的材料

接着,把镜头移到模型请求发送前。此时后台可能已有用户原话、组合结果、历史追问和基金资料。若一股脑全部塞进去,材料会拥挤;若各模块各自裁剪,关键限定条件又可能在交接中消失。模型真正收到的那一包内容,需要有人负责装配。

后台保存了材料,不等于模型看到了材料;工具刚返回正文,也不等于正文进入了当前请求。统一的上下文投影器 Projector 负责研究阶段的请求组装,让系统有一个明确位置回答:哪些内容最终被送进模型,哪些被省略,哪些只留在执行记录里。

投影器消费各模块已经获准提供的信息,包括当前问题、必要历史、工具转录、研究缺口、来源身份、技能指引和当前工具面。它将这些内容组织为模型请求,并按容量作机械拟合。它不自己读取数据库或网页,也不为资料授予新权限。业务模块提供事实,投影器组织模型需要的视图。

这里最重要的集中,是集中最终装配,而不是把所有业务都搬进一个文件。来源时间由来源模块解释,组合数字由计算模块提供,工具资格由执行层确认。投影器需要知道如何放入这些内容,却不应该重复维护各模块的业务规则。否则它会逐渐变成一个没有清楚边界的上下文总管。

历史背景同样经过投影。用户当前原话完整保留;历史用户内容可以按完整条目省略,助手回答可以总结。父任务中的来源、限制和研究背景各有自己的用途,不能把整个恢复账本直接交给模型,让它再次解释哪些事实可信。实际请求之后还做结构检查和工具面一致性检查,但这些检查不认证答案的语义正确。

单独封装 Projector,是把“生产事实”和“组织模型输入”分开。资料生产者只说明自己提供了什么,投影器集中决定如何装入本轮请求;容量处理与请求结构检查也在这条路径上完成。新增背景不再需要到多个适配器重复拼接。代价是投影器必须保持边界清楚,不能顺手接管取数、授权和业务解释。

05 技能:把研究方法从巨大提示中拆出来

模型知道要研究,还需要知道怎样研究。对基金报告,先核对产品和时间很有意义;对用户上传的表格,先弄清列含义可能更重要。把这些方法全部写进一个巨大提示,读者看着累,模型每轮也会携带大量与当前工作无关的说明。

技能承载可复用的任务方法。例如基金研究可以说明先核对对象和时间,再获取相关材料,最后区分事实、解释与未知;文档分析可以提醒模型关注版本、页段和限定条件。技能提供研究方向与表达要求,但不会替代运行时,也不会自行成为一个有独立权限的后台任务。

当用户显式调用已注册技能时,系统解析对应入口并准备技能背景;普通研究也会结合当前任务获得适用指引。最终可见工具仍由当前权限和服务事实形成,技能声明不能自动让一个工具可执行。技能需要的能力不可用时,系统应保留这个限制,而不是凭名字猜测替代能力已经获得授权。

我们希望技能减少方法的重复,而不是复制全部系统约束。通用行为、领域方法与工具使用说明各有主要归属:大家共用的要求应集中维护,领域技能只补充有意义的方法差异,参数与返回语义由工具契约说明。每新增一条指引,都应先看它是否能替换已有重复内容。

这项取舍来自实际维护成本。指引不断叠加后,同一要求可能同时出现在系统提示、技能和工具描述中,文字略有不同,升级时也容易只改其中一处。模型收到更多文字,却未必得到更清楚的方法。新增案例不一定意味着需要新增规则,有时更需要删除旧的重复解释。

技能将重复出现的领域方法收在一处,使同类任务共享研究顺序和表达习惯。通用规则留在公共指引,领域差异留在技能,参数说明留在工具契约。这样的封装服务于方法复用与维护,而不是增加提示层数。某条要求在多个地方出现时,我们优先找清归属;是否改善答案,仍需用实际任务检验。

06 个人背景与记忆:记住偏好,核对现状

用户又补了一句:“解释简洁一点,别默认我熟悉金融术语。”这类偏好以后可能仍有用;今天的基金份额明天则可能改变。两种信息都与用户有关,却需要不同的保留方式。助手若把一切都记成一句话,很快就会分不清偏好与现状。

连续使用助手时,用户不希望每次重新说明表达偏好和背景。但“记住我喜欢简洁回答”与“知道我现在持有什么基金”是两种不同需求。稳定偏好可以作为个人背景,组合状态则需要读取当前权威数据。把二者都存成自然语言记忆,会让过期状态和长期偏好混在一起。

当前个人背景投影用于提供有限、稳定的信息,长资料则通过获准检索按需读取。它们已经能支持上下文,但不等于完整的长期记忆系统。项目中的 Hybrid Memory 仍在推进生产闭环,不能因为有了存储和管理入口,就把自动学习、跨会话使用或遗忘机制都描述成已完成能力。

真正的记忆闭环,需要分别确认保存、读取、修订和遗忘。用户提出“记住这条偏好”只是请求,实际保存还需要回执;新会话使用旧偏好,需要核对范围和当前版本;用户纠正后,旧版本不应继续被召回;遗忘后,迟到的后台处理也不能把同一条内容重新写回来。

临时模式让这个问题更清楚。用户选择临时对话时,个人背景和记忆不能通过另一条默认路径悄悄进入。账户隔离同样需要在读取前成立,而不是先取出数据、再希望模型不要使用。记忆有用的前提,是用户能够理解和控制它的生命周期。

我们把短背景、按需检索和长期记忆分开讨论,正是为了分别处理容量、相关性和生命周期。当前文章能确认的是有限个人背景及检索路径;完整 Hybrid Memory 的生产闭环仍待补。它的引入背景是减少重复说明,但封装必须同时包含保存回执、纠正、遗忘与临时模式,才能让用户控制自己被记住的内容。

模型拿到了当前可见材料和方法,才有条件提出有意义的动作。材料包中的工具名称,接下来还要越过协议、权限与真实执行的边界。

第三层 · 能力接入与执行:一句“去查”,怎样成为事实

模型返回工具调用,研究终于要接触外部能力。此时有三个不同的交接:供应商协议变成本地事件,模型参数变成获准调用,工具原始结果变成可交给模型的投影。

我们封装网关、MCP 与 Host、钩子,是为了分别处理协议变化、能力执行和局部扩展。它们相邻,却不共享同一种修改资格。尤其在钩子上,历史评审发现“格式合法”仍能替换来源与数值,因此现在需要约束事实继承关系,而不只检查类型。

执行链:工具参数越过哪些交接

flowchart TD
    M["供应商返回工具调用"]
    G["网关解析完整调用"]
    N["规范化有效参数"]
    P["调用前钩子检查"]
    H["Host 准入与派发"]
    R["工具执行与真实回执"]
    Q["调用后钩子收窄"]
    V["下一轮可见材料"]
    M --> G
    G --> N
    N --> P
    P --> H
    H --> R
    R --> Q
    Q --> V

MCP 适配器接入能力,Host 管理实际执行。调用前检查不替代 Host 准入;返回后收窄的模型投影与原始回执各有归属。

扩展边界:收窄投影,保留事实

flowchart TD
    R["Host 工具事实"]
    O["原始输出与执行观察"]
    P["准备给模型的投影"]
    H["删除字段或数组项"]
    X["尝试改写来源或数值"]
    M["继承事实的较窄投影"]
    D["拒绝替换事实"]
    R --> O
    R --> P
    P --> H
    P --> X
    H --> M
    X --> D

这是调用后钩子的简化关系。原始回执独立保存;投影可以删除,留下的值与路径必须继承原事实。等形替换来源或数字属于禁止分支。

位置可以处理什么必须保留什么
模型网关协议适配、流解析、运输错误已收到的内容与实际中断位置
MCP 与 Host能力接入、参数校验、派发和回执当前权限、来源和执行身份
调用前钩子对当前动作做局部检查已规范化参数与 Host 权限边界
调用后钩子收窄模型可见投影保留下来的事实原值与路径
结束钩子观察结束过程已接受结束与正文交付的归属

07 模型网关:完整生成与半截响应之间

整理好的请求现在要越过本地系统,交给模型供应商。理想情况下,它返回完整正文或工具调用;设想连接在参数返回一半时中断,系统就得先辨认自己究竟收到了什么。半个调用无法靠“看起来差不多”变成一次有效动作。

模型网关负责把本地请求送到供应商,再将供应商输出转换成系统可以消费的事件。研究运行时选择当前获准路由,网关处理协议适配、请求运输和返回解析。模型可以选择研究动作,却不能选择任意外部地址、供应商凭据或系统没有接入的协议。

不同供应商的消息、工具调用和流式结束方式并不完全相同。网关需要保留正文、工具参数、终止原因和可得用量,同时判断流是否按协议完整结束。收到一些字节不等于收到完整调用,连接关闭也不自动意味着正常生成完成。运输层必须先明确实际取得了什么。

这个职责会影响失败恢复。排队时就失败、已经收到部分正文后断开,以及工具参数只返回一半,是不同情况。前两者可能保留不同的输出事实,最后一种不能直接进入工具执行。运行时决定是否还能重试,网关提供失败位置与已观测内容,避免把所有异常压成同一个“模型不可用”。

我们也需要限制网关的解释范围。供应商内部的分词、调度、缓存和隐藏推理不在本地可观测范围;只能记录协议实际提供的用量和诊断。没有返回某个费用字段,就应保留未知,不能根据普通响应成功推断成本完整。对性能原因的判断同样需要额外证据。

网关把协议差异收在系统边缘,让研究循环使用相对稳定的事件,同时保留中断位置与可得输出。它封装的背景是供应商格式与运输失败会变化,不能让这种变化扩散到每个业务模块。统一接口需要付出适配成本;抽象也必须留下有影响的差异,才能让上层判断恢复条件,而非把异常都压成一句失败。

08 MCP 与 Host:让“我去查”成为真实调用

模型这次提出了一个具体动作:读取组合,再找相关基金资料。文本中的“我去查一下”终于要变成实际调用。工具目录里有名字只是第一步,当前用户、当前任务和当前参数能否使用它,还要在真正派发前确认。

MCP 提供工具接入协议,Host 则管理一次具体工具调用如何进入执行。两者解决的问题不同:前者让能力可以被发现和描述,后者核对当前请求是否能使用这项能力。一个远端服务成功返回工具列表,只证明发现完成,不证明全部工具都适用于当前用户和任务。

研究阶段的工具面结合服务状态、资源权限和技能范围形成。模型看到工具后提出参数,Host 继续校验输入和实际访问条件,再执行并返回回执。示例中的组合查询和基金资料读取可以走不同适配器,但都需要明确的执行身份,不能靠模型声明“我有权限”越过接入边界。

工具结果也不是单一的成功值。返回部分材料、服务不可用、访问被拒绝和输入不合法,各自影响后续研究。模型可以根据这些结果调整策略,但不能把读取失败解释成资料不存在,也不能因为原工具拒绝就自动获得另一种访问权限。实际返回的提供者和来源仍需要保留。

在接入过程中,我们尤其注意发现阶段与执行阶段的故障。远端握手运输失败可以沿有界连接恢复处理,认证失败或非法工具描述却不应反复尝试掩盖。执行中的动作效果未知,又不能复用发现阶段的重试逻辑。它们都叫连接或调用失败,但需要不同的归属与恢复依据。

我们用 MCP 承接能力接入,用 Host 收口调用的校验、派发与回执,避免每个工具独立解释权限。接入新服务时,协议适配可以变化,执行身份和事实记录继续沿已有路径。这样封装的必要性来自能力数量与来源差异;其代价是明确处理发现、可见和执行这些不同状态,而不靠一个“工具已连接”概括全部。

09 生命周期钩子:给扩展留位置,也留清楚的边界

工具准备执行时,系统有时需要加一项局部检查;返回后,也可能只希望把部分字段交给模型。把这些需求直接写进每个工具,会让相同逻辑四处复制。钩子于是成为扩展位置,但它能做多少事,是接口设计中的关键问题。

钩子为既有执行链提供局部扩展位置。调用前可以检查当前动作,调用后可以收窄准备交给模型的结果,结束阶段可以观察运行。它们适合承载明确、局部的治理需求,但不应成为另一套研究策略,也不能因为可插拔就取得修改系统权威事实的资格。

调用前钩子收到当前调用与规范化参数,能够阻止对应动作。允许结果仍需经过 Host 的权限和资源检查,不能新增访问资格。调用后钩子工作在模型可见投影上,原始工具输出和 Host 执行观察保持独立。结束钩子在当前实现中是观察入口,不能作为答案质量裁判否决已接受的结束。

这里发生过一个很有代表性的问题:钩子输出通过了结构校验,却能够把来源、时间或数值替换成另一组同形内容。字段仍然叫来源和更新时间,验证器也认为格式合法,但它已经不再表达工具返回的事实。合法结构并没有保证事实继承关系。

修复后的约束是单调收窄。钩子可以移除字段或数组项,保留下来的事实必须保持原值和路径,不能添入新的事实。移除了影响完整计数的数据,也不能继续保留原来的完整覆盖声明。同步执行与异常处理则统一在钩子执行器中,避免扩展逻辑的失败逃逸成未处理错误。

钩子集中承接调用前检查、调用后收窄和结束观察,使工具本体专注于获取或处理数据。它封装的是明确的局部变化,不是第二套研究运行时。当前可注册扩展也不意味着每次调用默认都有额外规则。我们愿意限制扩展输出的自由度,保留来源事实与执行回执的归属,避免便捷定制悄悄变成重新解释事实。

到这里,“查询过”才有了真实回执。不过,拿到一段结果离解释用户的组合还很远:材料需要读,数字需要算,未知仍需要保留。

第四层 · 证据与计算:从找到材料,到形成可核对的判断

组合与资料进入研究后,最容易出现一种错觉:只要检索命中了、脚本跑完了,问题就解决了。我们的例子恰好需要继续追问:报告是否对应这只基金,段落还有哪些限制,分类覆盖了多少,数字能否复算?

这一层因此分成找材料、继续读材料、确定性领域计算和临时探索四项职责。封装背景是证据长度、版本与分析方式都在变化,而投资真值和生产规则需要稳定。研究可以按问题自由组合这几条路径;缺少行业穿透数据时,讲清覆盖缺口仍是有价值的结果。

证据消费:命中段落只是研究的中途

flowchart TD
    Q["当前研究问题"]
    S["检索与搜索候选"]
    C["核对对象、版本与来源"]
    R["按范围读取并保留位置"]
    G["缺少相关材料"]
    GP["保留具体覆盖缺口"]
    P["获准组合与计算结果"]
    M["解释、补读或说明未知"]
    Q --> S
    Q --> G
    S --> C
    C --> R
    G --> GP
    R --> M
    GP --> M
    P --> M

资料路径展示候选、读取与覆盖的区别;组合结果在后续推理中汇合。缺少材料可以形成明确缺口,不能被当作完整证据。

计算分工:生产数字与探索结果怎样汇合

flowchart TD
    D["已取得且获准的数据"]
    F["既有领域公式与规则"]
    P["临时 Python 分析方案"]
    N["可复算数字与输入口径"]
    E["实际输出、假设与回执"]
    M["模型解释并说明支持范围"]
    D --> F
    D --> P
    F --> N
    P --> E
    N --> M
    E --> M

两条计算路径使用各自适用的输入。确定性领域结果可复算,Python 分析保留假设与执行记录;模型最后解释用途和限制。

工作产物可以支持的结论
检索带来源的候选片段某些位置值得进一步读取
文档阅读已读取范围与可继续消费的材料这些具体内容已取得,可核对限定条件
领域计算有输入、口径与公式的结果指定条件下的数字可以复算
隔离分析带输入和假设的临时分析或文件分析已按记录执行,解释仍需审阅

10 知识检索:先找到值得读的地方

基金报告已经进入资料范围,但行业风险可能只藏在某几个段落。逐页阅读所有报告代价很高,按基金名字随便挑一段也不可靠。研究先需要一张材料地图:哪些地方最可能回答当前问题,再从这些线索继续读。

知识检索负责把用户问题连接到候选材料。文档预先经过解析、分块和索引,查询时用词法匹配与向量检索找到相关片段,再结合权限、来源和版本范围组织结果。它提供的答案是“哪些段落可能相关”,并不直接回答“整个问题已经得到充分支持”。

示例中的行业风险解释,可能需要基金报告里关于投资范围、集中度或特定行业的段落。基金简称相似,份额类别不同,历史版本也可能沿用同一标题,因此结果需要保留文档身份与版本。否则一次正确的语义匹配,也可能把另一份产品资料引入当前分析。

我们把检索质量进一步分开:材料有没有被召回,召回内容有没有进入模型,模型有没有正确使用。正确片段可能在后续请求拟合中被省略,也可能进入请求后被忽略;最后附上引用,也不证明模型解释没有越过原文。只观察检索返回成功,定位不了这些差异。

这一层可以使用结果融合、排序与邻接上下文提高候选质量,但是否值得增加重排或查询改写,需要来自实际失败。先用有限语料和固定问题找到错误阶段,比先选择新向量数据库更接近任务。评测应保留没有找到材料的样本,不能不断换简单问题直到检索看起来稳定。

检索模块把文档处理、索引与查询组织为可复用路径,让研究阶段取得带来源的候选片段。我们封装它,是因为找材料有独立的失败模式:对象不匹配、版本不对或关键段落没有召回。分开后,可以针对这些问题评测,而不直接修改答案提示。复杂排序是否值得引入,应由真实漏检与误检决定,不能仅靠组件名称判断。

11 研究资产与文档阅读:命中之后,还要继续读

检索找到一段“本基金可能面临行业集中风险”,但用户的问题还没解决。它前面可能有投资范围,后面可能有适用条件。研究于是从“找到相关段落”进入“沿这份材料继续读”。对长网页或 PDF,能够停下并接着读,比一次返回大字符串更关键。

检索负责找线索,研究资产负责让当前任务实际取得并继续阅读材料。网页、PDF 和生成文件可能远超过一次模型请求的容量,因此系统需要保留材料身份、版本、读取位置和覆盖范围,让模型可以按需取用,而不是把整份正文无差别塞进上下文。

在基金资料分析中,搜索结果先提供候选,网页读取获得正文,PDF 解析提供可定位的页段。搜索摘要与实际页段表达不同的证据强度:摘要可以支持有明确归属的摘要性陈述,但不能被描述成全文阅读;页码命中也不能自动证明前后章节没有进一步条件。模型需要根据剩余问题决定是否补读。

长材料的连续消费依赖实际句柄和游标。后续读取应沿已存在的材料身份前进,不让模型猜一个路径或文档标识。每次返回的范围与遗漏也需要保留。可继续读取的材料标识与答案引用各有用途:前者帮助导航,后者关联支持具体陈述的证据。这样,答案可以说明已经核对哪一段,而不会因为解析程序完成就宣称整份报告已经读懂。

缓存在这一层提供复用,但同时需要区分内容有效与访问有效。网页正文还存在,不代表当前用户仍有权展示;重新下载也不会改变原文描述的事实日期。当前运行中的材料与长期共享语料同样是不同范围,不能因为一次读取成功就自动进入后续所有用户的知识库。

我们将材料身份、读取范围和后续位置封装成研究资产,使网页、PDF 与生成文件可以沿清楚的消费路径交接。引入它的背景是模型上下文有限,而证据往往长且有版本。多出的元数据换来了定位和继续读取的依据,但缓存、访问有效性与事实日期也要分别管理。阅读模块保存已读范围,结论仍由研究形成。

12 确定性金融计算:让每个关键数字可以复算

到了计算环节,用户最容易核对的往往是一个数字。基金份额乘以当前净值得到市值,随后才能讨论占比;行业穿透还需要足够的分类与覆盖。若底层资料不全,答案就应保留未知,而不是用一个完整图表填满空缺。

组合当前市值、预算约束、基金份额与投资分配,都属于需要稳定来源和明确计算规则的结果。模型可以解释这些数字,却不应该通过自然语言重新维护它们。ETF Agent 保留确定性计算路径,使用权威组合事实与既有领域函数形成结果,再交给研究阶段消费。

示例中的行业暴露首先来自真实组合和可用分类数据。模型随后解释这些暴露可能意味着什么,不能在写答案时重新猜测持仓,也不能因为建议听起来合理就改变实际预算或操作状态。组合基本事实、研究判断和待确认建议必须保持不同身份。

计算本身也有适用条件。数据日期不同、分类口径变化或覆盖不全,都可能影响数字的解释。结果需要保留输入来源、单位、时间、公式含义和覆盖情况。程序正确运行只证明完成了运算,不证明输入已经适合当前问题,更不证明市场风险能够由一个数字完整表达。

一个容易被忽略的错误,是用陈旧资产快照配合新价格反推份额。这样会把本来稳定的持有数量变成随价格变化的派生值。我们把份额作为基本事实,估值随当前净值计算,让持仓事实与市场变化分别来自正确的输入。类似原则也适用于预算上限和未分配资金。

把领域计算从语言生成中单独封装,是让同一输入沿同一公式得到可复算的结果。模型拿到数字后解释风险,领域代码继续管理份额、预算与可执行约束。这个选择需要维护数据口径和边界,却让错误能够定位到输入或公式。组合研究可以很灵活,真实投资账本仍由原有确定性路径维护。

13 隔离分析:给临时研究一块动手空间

有了获准数据,用户可能还希望看一张对比表,或研究某种假设情景。为每种临时转换都新增业务工具,会让工具目录越来越长。此时,一个可以处理已取得数据的隔离分析环境,能给研究留出动手空间。

确定性金融计算负责既有权威结果,研究分析则需要更多临时操作,例如整理返回数据、比较序列、制作表格或模拟用户提出的情景。隔离 Python 为这类转换提供执行环境,输入来自当前研究实际取得且获准使用的数据,不把网络取数和投资真值重新计算都混进脚本。

模型提出分析方案,系统准备可用输入,脚本在隔离环境执行,再将结果作为研究材料返回。关键不是模型有没有写出正确语法,而是脚本实际消费了哪些数据、执行是否成功、输出对应什么假设。模型仍需要检查单位、日期和口径,遇到缺失输入时回到读取过程。

这种分析的结果不能自动获得权威身份。一个模拟脚本可以帮助理解行业集中对假设情景的影响,却不能覆盖既有分配算法或实际组合记录。程序返回成功,也不能说明公式适用于用户,更不能证明用户应该执行某项操作。运行事实与分析质量仍是两个问题。

生成文件还有独立的交付环节。脚本写出一张图或一份表格,只证明工作区里存在输出;用户能否下载,需要沿明确的导出路径确认。文件身份、输入关联和可用范围都需要保留,不能在正文里写一个猜测的地址就宣称产物已交付。

隔离 Python 承接临时数据转换、制表和绘图,把通用探索与确定性领域计算放在不同位置。它的封装背景是研究问题变化快,生产投资规则却需要稳定。分析结果继续带着输入与假设接受解释;生成文件则另走明确交付路径。这使一次脚本运行有可核对的范围,同时不会因解释器存在而新增投资执行资格。

研究现在拥有可以支持的解释,也知道哪些部分还缺材料。接下来要把这份进展交给用户,并让它在中断和后续追问中保持清楚的身份。

第五层 · 交付与连续性:答案来了,还要留得住、接得上

第一段答案出现时,用户的等待已经缓解,但系统工作尚未全部结束。正文可能先交付,后台保存随后结算;研究可能中断,用户也可能提出一条新的追问。画面、记录和任务关系需要各自说清发生了什么。

我们把发布、前端交付、恢复和接续拆开,背景来自这些不同时间轴。历史上的局部引用失败曾连带抹去正文,异步保存又可能让早读历史暂时为空。现在由对应模块分别处理局部降级、可见预览、耐久回执和新一轮关系,避免用一个“完成”概括整个交接。

交付分叉:可见正文与后台保存有各自时点

flowchart TD
    M["普通正文或答案片段"]
    P["统一发布处理"]
    A["已允许展示的正文"]
    S["服务端正文事件"]
    B["客户端接收与页面绘制"]
    D["后台持久保存"]
    R["保存回执与历史核对"]
    M --> P
    P --> A
    A --> S
    S --> B
    A --> D
    D --> R

这是正文已允许展示后的关系。浏览器收到内容与后台保存可以在不同时间结算,需要按同一正文身份核对,不能相互冒充成功。

继续分流:消息重发、任务续接与普通追问

flowchart TD
    U["用户再次提交内容"]
    R["原消息身份的重发"]
    C["显式继续父研究"]
    N["普通新追问"]
    RR["核对原运行与回执"]
    CR["新运行关联父任务"]
    NR["新运行使用获准历史"]
    W["沿当前资格恢复或研究"]
    U --> R
    U --> C
    U --> N
    R --> RR
    C --> CR
    N --> NR
    RR --> W
    CR --> W
    NR --> W

这张图按请求关系分流,省略每条路径上的权限与来源检查。普通追问和显式任务续接都可以建立新运行,重发则查找原消息。

用户看到的动作后台主要处理为什么要区分
同一消息重发复用消息身份,核对原运行避免重复创建研究
执行中断后恢复查回执与当前资格已执行与未知效果需要不同处理
继续未完成研究新运行关联父任务背景与限制保留,读取资格重新确认
普通追问新运行使用获准历史新问题主导研究,旧材料按需核对
回答澄清问题按已有澄清关系接续不能仅靠相似措辞绑定旧任务

14 答案发布:别让一处附件问题吞掉整段正文

现在,模型已经能写出一段有用解释,却仍有一份报告引用没有完全绑定。用户更关心已有结论和缺口;如果系统要求正文、所有附件和后台保存一起成功,局部问题就可能让整段答案消失。研究成果在最后交接处也会被卡住。

模型产生文本后,正文还需要进入发布路径,才能成为系统允许交付的答案。发布模块检查内容结构、来源引用、权限、数值绑定和依赖关系。当前模型通过 send_answer_part 提交独立成立的部分,普通助手正文也沿同一条路径处理。两种正文入口共享发布机制,读者无需根据生成形式猜测其可信程度。

我们在这里遇到的主要问题,是把正文、来源附件与后台保存绑成一个整体。研究已经形成有用解释,却可能因为局部引用不成立,最后整段内容没有到达用户。原本希望保证完整性,实际却让独立有效的内容被另一项失败连带抹去。

改动后的处理是按具体影响拆分。公开来源引用无法绑定时,可以降级引用并说明限制;无法核验的数值占位符需要明确标识,不能由模型补一个合理数字;权限、个人状态与投资权威的问题仍由对应边界阻止。一个局部警告不会自动推翻其他独立成立的正文。

逐步发布也要求控制重复。已经接受的答案部分可以被后续新发现补充,真正纠正时需要指向对应部分,而不能跨回合重复追加同义内容。finish_research 用于提出结束研究;正文仍由发布路径交付。结束状态与答案内容分别记录,才能发现研究停止后是否还有结论没有送出。

发布模块集中接住普通助手正文与答案片段,分别处理内容、引用和受保护数据。封装这一层,是为了让模型输出到用户正文之间有可核对的转换,而不把每种生成入口各做一套检查。局部问题按影响降级或阻止对应效果;已有独立内容可以保留。这需要更细的状态,但避免把附件问题扩大为整答失败。

15 事件交付与前端:从后台生成到用户看见

页面终于出现第一段解释。设想用户立刻切回历史,再回来时后台保存还没结算:画面该相信已收到的正文,还是刚读到的空历史?这不是字体和动画问题,而是即时交付与耐久记录之间出现了短暂时间差。

供应商流和浏览器流是两条不同链路。供应商返回模型正文与工具参数,服务端先处理研究、执行和发布;浏览器接收的是系统自己的正文、活动和终态事件。前端不会原样显示模型隐藏推理或完整工具输出,也不能把供应商每一个增量都当作获准答案。

浏览器解码事件后,按正文身份、版本和顺序关联内容,再更新页面。工具活动用于说明可观察的执行进展,答案部分用于呈现研究结果。显示动画只表达界面行为,不证明模型仍在逐字生成;一个完成事件也不天然证明用户已经读到全部内容。

当前路径允许获准正文先可见,后台再保存。这会产生一个短暂窗口:页面已经有内容,耐久历史还没有相应正文。如果前端立即用空历史覆盖当前画面,用户会看到答案消失。解决这个问题需要识别同一视图、同一运行的有效预览,而不是无条件保留所有本地内容。

前端因此在严格匹配、服务端仍处于待保存状态且没有撤权信号时暂时保留预览,并继续只读核对历史。视图切换、访问失效或更新后的权威历史不能沿用这项例外。刷新时也只信任当前获准投影,不能把过去收到过的正文当成永久显示资格。

事件交付与前端消费独立封装,使浏览器接收获准正文和活动事件,再按身份与版本更新视图。它的背景是模型流、服务端交付和页面绘制各有时点,不能沿用同一成功信号。预览保留必须匹配当前运行并受访问状态约束;耐久历史回来后再核对。用户因此可以及时看到内容,系统也仍能诚实说明保存状态。

16 持久恢复与失败重试:从事实接手中断的研究

研究还在继续时,连接可能断开,进程也可能重启。已有一份报告读完,另一项动作结果未知:全部重做会重复工作,全部跳过又可能遗漏关键证据。恢复首先要重建发生事实,然后才能讨论是否再试一次。

恢复的起点是执行记录,不是重新播放整段对话。系统需要知道哪些模型回合已经封存、哪些动作实际执行、哪些结果有回执、哪些正文已经保存,以及当前运行是否仍被允许推进。数据库保留这些事实,运行时据此决定回放、继续执行或停止。

已经完成的工具动作不应因为进程重启再次调用;动作效果未知,也不能被当成从未发生。取消、来源撤销和新租约同样会改变恢复资格。旧执行者不能拿着过期状态覆盖新结果,历史回执也不能自行扩大当前访问范围。恢复需要比普通流程更认真地确认事实归属。

失败重试则是恢复中的一种动作选择。模型运输故障、工具发现失败、后台保存失败有不同条件,不能共享一个“遇错重跑”的无限循环。每种尝试由对应模块管理,消耗实际资源并保留失败。永久拒绝、取消和未知效果尤其不能被自动尝试掩盖。

一项重要取舍,是把模型请求重试与工具重派分开。模型重新生成,不意味着可以重新执行此前所有动作;读结果回放只消费既有回执,也不等于再次读取外部来源。这样,研究可以继续利用已经发生的工作,同时保留哪些环节没有完成。

恢复层把回执、检查点、执行资格和当前运行状态组织在一起,让重新进入的执行者知道从哪里接手。重试继续归属于模型运输、工具连接或保存等具体模块,避免一个通用重跑按钮制造重复效果。我们把客观状态放在这里,正是因为它不适合由模型回忆;代价是维护状态转换和并发写入的明确规则。

17 多轮对话与任务接续:同一句“继续”的不同含义

第一轮解释结束后,用户追问:“科技行业暴露主要来自哪些基金?”界面仍是同一个聊天框,后台却应该开始一轮新研究。它需要理解上一轮背景,同时核对当前资料;与刚才断线后的重发相比,这次“继续”有完全不同的含义。

多轮对话与同一运行恢复不能混为一谈。用户补充问题,通常会创建新的运行;显式继续尚未完成的研究,则创建关联父任务的运行;浏览器断线重发才是复用原消息身份。它们可能在界面上都表现为“继续”,后台却需要不同的事实与权限处理。

普通追问使用当前获准历史,保留必要背景。示例里的“科技行业暴露来自哪些基金”可以承接上一轮答案,但仍然是一条新请求。它不会自动继承过去所有工具结果,也不能因为同一会话曾读取过个人明细,就永远拥有这些资料。

显式任务接续会关联父运行,核对父任务资格、限制和可用研究背景。父任务中的禁止条件不能因为新消息省略它就消失;旧来源与读句柄则不能成为新运行的权限。系统需要把“保持任务约束”与“重新确认当前读取资格”同时做到,不能用一份历史对象替代两种判断。

澄清有独立语义。模型询问必要条件后,用户下一条回复可能是对该问题的补充,系统按现有澄清关系接续并核对回执。它与普通追问不同,但也不能依靠一句相似措辞绑定任意旧任务。显式接续无法确认时,尤其不能静默选择一个更宽松的解释。

接续模块独立管理普通追问、澄清回复与显式任务续接,减少依靠相似措辞猜测关系的机会。封装的背景是聊天连续性与执行连续性会相互混淆:历史帮助理解问题,当前权限和来源时间仍需重新确认。它保留约束与相关背景,也保留新问题的主导地位,让用户自然推进交流,而不让旧任务自行恢复动作。

用户可以继续问下一个问题,系统也留下了可核对的交付与保存状态。最后还要从另一条视角检查:哪里可能失真,以及这份答案到底有没有帮助。

第六层 · 观测与评估:让“发生了什么”和“答得怎样”各有依据

故事走到这里,答案已经可以出现,但技术介绍不能以“页面有字”收尾。我们还需要回答两个问题:这次过程在哪些位置有缺口,最终解释是否满足最初的请求?

观测贯穿前面所有层,评估回到用户任务,两者并不是流程末尾串行执行的两个按钮。我们将它们单独封装,是因为工具成功、执行完成、正文保存和语义质量来自不同事实。历史诊断中的早读空记录与 trace 缺尾段也提醒我们,观察时点本身会影响判断。

观测关联:沿同一运行拼回事实,而非拼出成功

flowchart TD
    I["同一运行关联身份"]
    M["实际模型输入与输出"]
    T["实际工具回执"]
    A["服务端正文交付观察"]
    D["耐久保存与正文一致性"]
    U["独立界面观察:有则记录"]
    O["Langfuse 关联视图"]
    I -.-> M
    I -.-> T
    I -.-> A
    M -.-> O
    T -.-> O
    A -.-> O
    D -.-> O
    U -.-> O

Langfuse 关联可取得的观察。界面绘制需要独立观测;未取得时保持未知。观测异常不会改变真实执行与正文保存。

质量回看:从原问题和实际交付出发

flowchart TD
    Q["固定任务与原用户要求"]
    A["实际交付与可核对依据"]
    R["复算与显式语义评审"]
    P["支持的部分通过"]
    F["失败部分定位原因"]
    U["未知或未评审保留"]
    M["沿责任归属修复对应模块"]
    Q --> R
    A --> R
    R --> P
    R --> F
    R --> U
    F --> M

评估使用固定任务和明确评审对象。通过、失败和未知都保留;修复先回到失真模块,避免把所有问题都变成新增提示。

观察维度回答的问题不能从它直接推断什么
生成模型是否形成候选正文?正文已经交付
交付哪个界面或通道实际观察到正文?服务端发出即用户已看见
保存同一运行正文是否耐久存在?已解决整道题
一致性独立交付与保存正文是否一致?内容语义正确
执行运行停止在什么状态?答案有用
质量显式评审认为哪些要求满足?未评审部分自动通过

18 Langfuse 观测:沿真实交接寻找第一个失真点

如果最后有人指出“你没有结合那份报告”,从答案倒推很难知道原因。报告可能没有取到,可能在请求组装时省略,也可能已进入模型却被错误解释。我们需要回到当轮实际输入和执行记录,让怀疑有一个可以核对的位置。

只看最终答案,很难知道失败发生在哪里。模型没有生成正文、工具没有返回、发布拒绝、保存未完成或浏览器断线,都可能让用户说“没有回答”。Langfuse 把输入、逐轮模型交换、工具事实和正文记录关联到具体运行,帮助我们沿数据路径定位第一个失真环节。

最有价值的观察往往是实际模型输入。后端有材料不代表进入请求,模型自称读过也不代表存在工具回执。逐轮输入输出与实际调用记录可以互相对照,让调查从“模型可能不听话”推进到“材料在这一轮被省略”或“结果被错误解释”这样的具体问题。

观测自身也曾制造误判。正文已经显示,后台保存尚未结算,立即查询会看到空记录;后台仍在提交时关闭观测通道,又会让数据库有正文、trace 缺尾段。缺失可能来自观察时点与通道生命周期,不能直接归因为模型没有回答或正文已经丢失。

当前答案结果把生成、交付界面、持久保存、正文一致性、执行状态和语义质量分开记录。服务端发出内容不等于浏览器绘制内容,保存部分答案也不等于整道题完成。正文指纹帮助核对独立观察是否一致,未知与未评审保持自己的状态,不被自动填成通过。

Langfuse 将分散的请求、模型交换、工具与正文观察关联起来,服务于跨模块调查。它封装的背景是单个模块日志看不见完整交接,而且异步保存与观测提交有自己的时点。当前结果分别记录生成、交付、保存、一致性、执行和质量;每列保留事实来源。观测越清楚,越应允许未知存在,而不是由一个 span 代替所有结果。

19 质量评估:完成之后,仍要回到用户的问题

看见一段流畅答案之后,还剩最难的问题:它真的帮助用户理解自己的组合了吗?一个回答可以数字正确却漏掉时间条件,也可以解释合理却没有送到页面。评估要沿最初的问题回看实际交付,让过程记录与答案价值相遇。

观测回答“发生了什么”,评估回答“结果是否满足用户问题”。工具调用成功、正文非空或运行完成,都不能单独证明答案有用。示例中的行业风险解释,至少要核对组合数字、来源口径、推导是否成立,以及用户要求的缺口说明有没有真正交付。

质量检查需要回到原输入与实际输出。模型候选文本可以帮助调查,但评审对象应说明是候选答案、服务端交付还是用户可见结果。不能用未送出的好答案替已经交付的空内容通过,也不能把正确主结论掩盖附加数字或引用上的错误。

固定问题集帮助观察版本变化,保留集则减少对已知案例的过度适配。失败、无结果和观测未知都应留在分母里。只统计拿到回答的题目,会把运输与交付问题排除在用户体验之外;反复换题或只展示最好的一次,也无法说明系统在同一类任务中是否稳定。

语义评审可以来自人工或模型,但都需要明确依据。模型打分不是事实认证,两个模型对同一错误输入意见一致也不能建立可信度。确定性计算适合复算和边界测试,解释质量则需要查看材料是否支持结论。不同检查提供不同证据,不需要被压成一个总通过率。

把评估独立封装,是给系统保留一把与执行状态不同的尺子。固定任务与实际输入输出用于比较变化,领域数字复算,解释与引用接受语义评审,失败和未知留在样本里。评估结果再指向需要修复的模块。没有长期测量时,我们能讲清设计与已知行为,仍应把更准、更快或更稳定留给相称证据。

下一次出现坏答案时,先沿交接找到第一个失真点,再决定修复材料、投影、执行、研究策略还是前端。模块边界在此成为调查路径,而非目录装饰。

回到聊天框:这些封装究竟换来了什么

用户继续问科技行业的来源时,系统不会从空白开始:它有同一会话中的相关背景,也有新一轮的执行身份。模型可以沿当前可用资料继续研究,代码仍保存真实动作与计算结果,正文则沿明确路径交付。

这六层、十九个模块区分的是职责,未必对应十九个服务。它们各自承接一种变化:交互变化由入口处理,方法变化由技能承接,供应商变化留在网关,材料变化进入检索与阅读,交付时间差由前端和持久层核对。单纯问答未必需要全部结构;有个人数据、长证据、多轮研究与故障恢复时,这些问题会逐步出现。

我们最值得保留的几次调整,都发生在交接处:让模型提议动作,把执行账本留给运行时;让钩子定制可见投影,保留工具事实;让正文、附件、保存与质量分别表达结果。它们没有自动证明答案更准,却让坏答案有了更具体的调查入口,也让局部失败更容易被如实交给用户。

下一次再看聊天框里的“已完成”,更值得问的是:完成了哪一件事,依据在哪里,用户实际拿到了什么?