Agent day_2:finish_reason状态、token种类及含义、流式和非流式回复的区别、K-Value、Agent记忆(短期、长期、工作记忆)、摘要压缩
day2学习路径memorytoolskillsubagentmcpCompletion( modelglm-5.2, created1785462550, choices[ CompletionChoice( index0, finish_reasonstop, messageCompletionMessage( content《夏居漫兴》。, roleassistant, reasoning_content1. 。, tool_callsNone ) ) ], request_id2026073109484499f67ea68c2848ec, id2026073109484499f67ea68c2848ec, usageCompletionUsage( prompt_tokens174, prompt_tokens_detailsPromptTokensDetails( cached_tokens0 ), completion_tokens1550, completion_tokens_detailsCompletionTokensDetails( reasoning_tokens1379 ), total_tokens1724 ), objectchat.completion )finish_reason的状态有哪些finish_reason 状态详细含义常见原因及应对策略stop(最常见)自然结束模型已完整回答问题或者遇到了设定的停止字符stop sequence。这是最正常的结束状态。length/max_tokens达到最大 Token 限制生成内容达到了请求中设置的max_tokens限制或者触发了模型的上下文最大长度上限。此时文本可能已被强行截断。如果需要完整输出可以调大max_tokens或接着提问“继续”。content_filter/safety触发安全或内容过滤机制生成的内容触及了模型的敏感词过滤、安全策略、版权限制或道德审查规则导致生成中断。tool_calls/function_call触发函数/工具调用模型决定暂停文本生成转而请求调用外部工具或 API例如查询天气、检索数据库。客户端需要先执行工具并回传结果。null/null未定义仍在生成中通常出现在流式传输Streaming过程中表示当前 Chunk数据块不是最后一个模型还在继续生成。error/failed系统或网络异常生成过程中服务器端发生内部错误、请求超时或后台异常终止。token的各种含义token---模型处理文本的基本单位具体数量取决于模型的tokerizer常见的tokeninput_tokens/prompt_tokens输入token数量----发送给模型的内容长度包含system promptdevelper messageuser message历史对话tool返回内容output_tokens/completion_tokens模型生成的token数用户最终看到的回答模型内部推理 token如果模型计费/统计时暴露其他生成内容例如某些隐藏步骤total_tokens总token数total_tokens input_tokens output_tokensmax_tokens限制模型最多生成多少token限制-----output_tokensContext windows(上下文窗口)模型一次能处理的最大token数cached_tokens缓存token系统重复使用、无需重复计算处理的那部分Token当向大模型发送请求模型需要理解你输入的所有文本(Prompt)。如果每次请求都包含大量重复或固定不变的内容系统就会把这部分内容的“中间计算状态”在服务器端缓存起来下一次你再发生类似的请求时重复的内容直接读取缓存--标记cached_tokens(费用更便宜、速度更快)新增/变动的内容正常计算--标记为普通prompt_tokens(按标准价格计费)产生场景长系统提示词(System Prompt)长文档/代码库问答多轮对话reasoning_tokens推理tokenvisible_tokens用户实际看到的输出名称含义input_tokens输入文本 token 数prompt_tokens旧接口里的输入 tokenoutput_tokens模型生成 tokencompletion_tokens旧接口里的输出 tokentotal_tokens输入输出max_tokens最大生成数量限制context_length模型最大上下文容量cached_tokens缓存复用 tokenreasoning_tokens内部推理 tokenvisible_tokens用户可见 tokencreate秒级----日期from datatime import datetime timestamp1700000 #转换为本地datetime对象 dt_localdatatime.fromtimestamp(timestamp) ​ formatted_timedt_local.strftime(%Y-%m-%d %H:%M:%S)常用格式化占位符参考%Y四位数年份如 2026%m两位数月份01-12%d两位数日期01-31%H两位数小时00-2324小时制%M两位数分钟00-59%S两位数秒数00-59流式和的非流式回复的区别流式Stream/增量输出SSE/Websocket分片推送用户提问 → 实时推送【思考文本】“我需要查询天气工具” → 后台同步调用工具 → 工具返回数据 → 继续流式输出最终回答非流式一次性返回/阻塞式用户提问 → Agent思考→决定是否调用工具→执行工具→拿到结果→交给LLM生成完整回答→一次性返回全部文本对比项非流式回复流式回复数据推送时机全部内容生成完毕一次性返回生成一段推送一段持续分片输出用户体验长时间空白最后突然弹出完整答案等待感强逐字实时输出类似 ChatGPT 打字效果感知更快网络协议普通 HTTP 请求Response 一次性返回主流SSE (Server-Sent Events)长连接 Websocket耗时感知感知耗时 真实总耗时用户必须等到结束才能看到内容感知耗时大幅缩短首字符很快输出不需要等待全文完成Agent 工具调用场景工具调用、多轮规划全部执行完成后才输出文字两种模式①思考过程流式输出②先输出思考文本后台并行调用工具服务端内存短请求占用内存低一次性组装完整响应需要持续维护连接长连接更多连接管理成本更高中断能力请求发起后客户端中途取消很难终止服务端任务客户端可以随时断开连接服务端可及时停止推理节约算力适用场景后台批量处理、接口数据同步、文档导出、不需要实时展示对话机器人、Web 聊天界面、AI Agent 前端交互、实时问答维度流式回复 (Streaming)非流式回复 (Non-Streaming)数据传输方式分块实时推送如 Server-Sent Events / WebSockets单次 HTTP 请求/响应请求 → 等待 → 一次性返回首字延迟 (TTFT)极低通常百毫秒级即可看到第一个字/动作高必须等待整个 Agent 流程结束过程透明度高可实时展示 Agent 的思维链、工具调用状态低等待期间为黑盒状态用户只能看到加载动画网络与连接长连接对网络稳定性要求高短连接遵循标准 RESTful 设计用户可打断性支持用户随时可以点击“停止生成”不支持只能等待请求超时或取消整个 HTTP 请求SSE(Server-Sent Event)基于HTTP协议实现客户端向服务器发送一个普通的HTTP请求并在请求头指定Accept: text/event-stream服务器响应后不关闭连接保持HTTP连接通道打开(也就是“流”式传输)之后每个事件服务器都按照固定的格式推送到客户端直到服务器关闭连接对比维度SSE (Server-Sent Events)WebSocket数据流向单向服务器 $\rightarrow$ 客户端双向客户端 $\rightleftarrows$ 服务器底层协议标标准 HTTP / HTTP/2WebSocket 协议由 HTTP 升级而来数据格式仅支持UTF-8 文本支持文本及二进制数据Blob/ArrayBuffer断线重连浏览器内置自动重连与状态续传需要在代码中自行编写断线重连逻辑代理与防火墙完全兼容现有 HTTP/Nginx/CDN 基础设施部分老旧防火墙/Nginx 代理可能需要专门配置Upgrade开发复杂度前后端极其简单前端只需new EventSource()稍复杂需要维护连接状态、心跳检测Heartbeat等流式回复代码from zai import ZhipuAiClient ​ from dotenv import load_dotenv ​ import os ​ import zai ​ load_dotenv() ​ zhipuai_api_key os.getenv(ZHIPUAI_API_KEY) zhipuai_model_name os.getenv(ZHIPUAI_MODEL_NAME) ​ client ZhipuAiClient(api_key zhipuai_api_key) ​ message[ {role:system,content: 你是古典诗人专攻中华传统诗词擅长五言、七言绝句、律诗、宋词、小令。 约束 1. 若用户要求格律作品严守平水韵对仗工整不出现现代词汇。 2. 风格可选山水、怀古、咏物、抒怀、赠友、羁旅。 3. 不作超长白话不混入网络用语。 4. 用户未指定体裁优先创作绝句如需填词请主动询问指定词牌。 5. 完成诗作后可按需附上简要释义不冗余。 } ] while True: try: user_input input(你 : ).strip() # 你 小狗的故事 ​ if not user_input: continue ​ if user_input in[q,exit,quit]: break; ​ message.append( {role:user, content: user_input} ) ​ #返回的可迭代对象(Stream Iterator)不是传统的数据对象 response client.chat.completions.create( model zhipuai_model_name, messages message, #流式 stream True, ) #print(response.choices[0].message.content) #不会打印出任何具体的回答内容而是会打印这个Stream对象的类信息和内存地址 print(response,response) #print(response.model) #print(response.created) #print(response.choices[0].finish_reason) #print(response.choices[0].message.content) reply ​ for chunk in response: #print(chunk :,chunk) data chunk.choices[0].delta if data.content: print(data.content,end,flushTrue) reply data.content ​ print(fAI 回复 :{reply}) except zai.core.APIStatusError as err: print(fAPI 状态错误 {err}) ​ except zai.core.APITimeoutError as err: print(f请求超时 {err}) ​ except Exception as err: print(f其他错误 {err})重点理解#返回的可迭代对象(Stream Iterator)不是传统的数据对象 response client.chat.completions.create( model zhipuai_model_name, messages message, #流式 stream True, ) #print(response.choices[0].message.content) #不会打印出任何具体的回答内容而是会打印这个Stream对象的类信息和内存地址 print(response,response)K-ValueKnowledge Value一条知识对于当前Agent任务的有效价值Agent的知识价值评分机制Agent为什么要检索某条知识、这条知识值不值得相信、应该在多大程度上影响最终决策组成Relevance:相关性这条知识和用户当前问题有多相关Reliablity:可靠性知识本身是否可信Freshness:时效性知识是不是最新的Completeness:完整性这条知识能不能完整解决问题例如“退款需要联系客服。”信息价值有限。但“购买后 7 天内可申请退款登录订单页面 → 售后 → 退款申请审核通常需要 1–3 个工作日。”明显更有价值。Specificity:针对性知识是否针对当前用户、产品、场景例如普通用户退款规则和企业客户退款规则对于不同用户价值完全不同。一个简单的 K-Value 公式如果自己做一个小型 Agent可以简单定义KWr•RWt•TWf•FWc•CWs•S其中R Relevance相关性T Reliability可信度F Freshness时效性C Completeness完整性S Specificity针对性RAG 负责“找知识”K-Value 负责“判断知识的价值”Agent 负责“利用知识完成任务”。Agent记忆感知 → 读取上下文/记忆 → 思考 → 调用工具 → 得到结果 → 更新状态/记忆 → 继续执行记忆的类型层次常见名称作用生命周期① 当前输入Input当前用户告诉它什么当前请求② 工作上下文Context / Working Memory当前任务正在处理的信息当前任务/会话③ 会话状态StateAgent 当前做到哪一步通常持续整个任务④ 短期记忆Short-term Memory保存任务过程中的临时信息任务期间⑤ 长期记忆Long-term Memory保存用户、项目、经验等跨任务/跨会话⑥ 外部知识RAG / Knowledge从数据库、文档、网页等检索信息外部持久化长期记忆 Long-term Memory能够跨越当前任务/会话长期保存并在未来再次使用的信息。例如 Agent 知道用户偏好- 喜欢简洁回答项目知识- 项目使用 Python 3.12历史经验- 这个项目部署前必须执行 migration特点保存时间长不需要一直放在当前 Context通常存在数据库、向量库、文件等外部存储需要时再检索出来核心问题“以后还值得记住什么”短期记忆 Short-term Memory为了当前一段时间或当前任务暂时保留的信息。例如 Agent 正在修 CICI 当前失败失败发生在 test已经修改 xxx.py第一次修复失败正在检查依赖版本任务结束以后这些信息可能就不再需要。特点生命周期短容易被更新、覆盖、丢弃服务于当前任务/会话核心问题“现在暂时需要记住什么”工作记忆 Working Memory在当前任务中Agent 正在主动使用、操作和更新的信息。长期记忆 │ Retrieval / 检索 ↓ ┌─────────────────────────────────────┐ │ Working Memory │ │ │ │ Goal │ │ State │ │ Plan │ │ 当前事实 │ │ 中间结果 │ │ 历史摘要 │ │ 检索到的长期记忆 │ │ 最近工具结果 │ └──────────────────┬──────────────────┘ │ ↓ Context Management │ ┌───────────┼───────────┐ ↓ ↓ ↓ 摘要化 压缩 筛选/截断 │ │ │ └───────────┼───────────┘ ↓ Final Context ↓ LLM ↓ Action / Tool ↓ 新信息 │ ┌──────────┴──────────┐ ↓ ↓ 更新工作记忆 提取长期记忆 ↓ Memory核心工作记忆Agent为了完成当前任务暂时保存并持续更新的关键信息Working Memory / Short-term State它不是让模型“永久记住”而是让 Agent 在执行一个复杂任务时保持连续性。Working Memory ↓ Context Management ↓ ┌───────────────────┐ │ Retrieval │ │ Filtering │ │ Summarization │ │ Compression │ │ State Selection │ └───────────────────┘ ↓ Final Context ↓ LLMAgent的Memory一般主动读取┌──→ Long-term Memory │ User → Agent → 判断需要什么信息 │ ├──→ Vector DB │ ├──→ SQL │ ├──→ 文件系统 │ └──→ Web ↓ 得到相关信息 ↓ 加入 Context ↓ LLM ↓ 下一步行动Agent可以需要时候检索记忆总结AI Agent │ ┌──────────┴──────────┐ │ │ 当前任务 长期信息 │ │ ↓ ↓ Working Memory Long-term Memory │ │ ↓ ↓ Context ←────── Retrieval ──────┘ │ ↓ Context Window │ ↓ LLM │ ↓ Reasoning / Action │ ↓ Tools │ ↓ 新的 Observation │ └────────→ 更新 State长期记忆 │ ↓ 检索 │ ↓ History ───────→ Working Memory ←────── Tool Results ↑ │ State / Plan │ ↓ Context Management │ 摘要 / 压缩 / 筛选 ↓ LLM Context会话上下文记忆当前单次会话内的对话历史直接拼接进大模型的上下文窗口随会话结束释放每轮对话自动追加用户的提问与助手的回答维持单论对话的语境连贯性管理策略:固定轮数窗口只保留最近N轮对话避免上下文溢出固定Token窗口按Token数量限制超出则截断最早对话摘要压缩对话过长时用大模型将历史压缩成摘要节省Token滑动窗口原生 条数变种 Token滑动窗口摘要压缩轮次摘要、关键点提取摘要维度轮次摘要 (Turn-based)关键点提取摘要 (Key-point)压缩依据时间顺序 / 轮次数量语义重要度 / 状态变更数据结构纯文本非结构化段落JSON / Key-Value / 知识图谱结构化Token 消耗随对话增长平缓上升非常紧凑长期维持低位信息准确度保留叙事和推演过程保留精炼结论和状态约束适用场景角色扮演RP、开放式聊天、客服系统Task-oriented Agent、代码助手、多工具调用 Agent