AI回答太冗长?我设计了三段式流式显示让信息层次分明
我是张大鹏做了十多年人工智能带过不少项目。说实话最难的不是让AI生成正确的答案是让答案以正确的方式呈现给用户。最近Claude 3.7推出了extended thinking模式OpenAI的o系列也在做类似的事情——让AI的推理过程可见。但我们在如意Agent里做这件事的时候发现单纯的显示思考过程不够用户真正需要的是信息分层。一、传统AI输出的痛点用过ChatGPT或Claude的都知道AI回答问题的典型流程是你提了一个复杂问题屏幕开始滚动AI滔滔不绝你盯着屏幕看了30秒还没看到重点最后发现答案藏在第8段前面全是推理过程这种一镜到底的输出方式在简单问答时没问题。但在多轮工具调用、复杂推理的场景下体验很糟糕场景问题用户感受工具调用AI先思考用哪个工具再调用再分析结果再决定下一步“到底在干嘛进度多少了”长推理1000字的思考过程最后结论只有50字“前面这么多字就为了说这么点事”多轮对话历史上下文混在一起新信息被淹没“好像之前说过这个是不是重复了”我们的核心需求很明确让思考过程可见但不干扰让结论突出但不突兀让详细回答有序但不冗长。二、三段式流式显示设计基于上面的分析我们设计了thinking / summary / answer三段式流式显示。2.1 三段定义段落内容显示策略目的thinkingAI的推理过程、工具调用分析、策略调整可折叠默认收起满足好奇心不干扰阅读summary极简单行概括30字包含关键结论独立高亮显示快速获取核心信息answer详细回答、代码示例、数据表格主体展示获取完整信息2.2 消息协议设计后端流式输出的消息格式classMessageBlock(BaseModel):type:Literal[thinking,summary,answer]content:stris_complete:boolFalseWebSocket推送时每个block独立发送{type:thinking,content:正在分析项目结构...,is_complete:false}{type:thinking,content:发现3个相关模块优先检查handler层,is_complete:true}{type:summary,content:问题根源在HTTP流重试逻辑建议检查第47行,is_complete:true}{type:answer,content:详细分析如下...,is_complete:false}关键点type字段让前端知道当前收到的是什么内容is_complete字段标记段落是否结束用于UI状态更新独立推送保证即使thinking很长summary和answer也能及时到达2.3 前端渲染策略终端版Rich的实现fromrich.liveimportLivefromrich.panelimportPanelfromrich.markdownimportMarkdownfromrich.layoutimportLayoutclassStreamingDisplay:def__init__(self,console):self.consoleconsole self.thinkingself.summaryself.answerself.show_thinkingFalse# 默认折叠defupdate(self,block:MessageBlock):ifblock.typethinking:self.thinkingblock.contentelifblock.typesummary:self.summaryblock.contentelifblock.typeanswer:self.answerblock.content self._render()def_render(self):layoutLayout()# summary 始终显示在最上方ifself.summary:layout.split_column(Layout(Panel(f{self.summary},stylebold cyan)),Layout(self._build_main_content()))else:layoutself._build_main_content()self.live.update(layout)def_build_main_content(self):# thinking 可折叠ifself.show_thinkingandself.thinking:thinking_panelPanel(self.thinking,title 思考过程,styledim)else:thinking_panel# answer 主体answer_panelPanel(Markdown(self.answer),title如意Agent)returnLayout(thinking_panelanswer_panel)Web版Vue3的实现更简单用v-if控制折叠template div classmessage-blocks !-- summary 始终显示 -- div v-ifsummary classsummary-block {{ summary }} /div !-- thinking 可折叠 -- div v-ifthinking classthinking-section button clicktoggleThinking {{ showThinking ? 收起 : 查看思考过程 }} /button div v-showshowThinking classthinking-block {{ thinking }} /div /div !-- answer 主体 -- div classanswer-block v-htmlrenderedAnswer/div /div /template三、后端解析实现三段式的核心难点在解析LLM返回的是纯文本流如何从中提取出thinking、summary、answer3.1 标签约定我们在system prompt中要求LLM按固定格式输出thinking 分析当前情况... 决定使用哪个工具... /thinking summary 极简单行概括30字 /summary 详细回答... 代码示例...这个约定有几个好处结构化标签明确解析简单向后兼容不支持标签的LLM内容会全部落入answer可扩展未来增加新段落类型只需加新标签3.2 流式解析器解析器需要处理流式输入不能等全部内容到达再解析importrefromtypingimportGeneratorclassStreamParser:def__init__(self):self.bufferself.current_blockNonedefparse(self,text_stream:Generator[str,None,None])-Generator[MessageBlock,None,None]:流式解析文本实时产出MessageBlockforchunkintext_stream:self.bufferchunk# 检查是否完整捕获了一个标签块forblock_type,patternin[(thinking,rthinking([
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2589566.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!