从调用到闭环:组装 Agent 的 Tool、Context 与输出合约
上一篇文章里我把 Pi 这个对话骨架跑通了能聊能接住用户的话也能给个像模像样的回答。但距离“能用”还差一步模型不知道什么时候该调用工具工具返回的数据也没法稳定地喂回给模型模型输出的内容更没有一份双方都认的格式约定。这其实就是标题里说的三件事Tool、Context 和输出合约。Pi 不是一个聊天玩具它是我在本地组装的一个小型 Agent 原型目标是通过大模型接口把“能听会说”升级成“能动手”。而这个“动手”能力全靠 Tool 提供工具怎么被正确调用取决于 Context 怎么组装工具执行完的原始结果能不能被用户读懂、被下游流程消费又取决于输出合约。这三样东西单独拎出来每一样都不复杂但真正难的是把它们焊成一个整体。这篇文章就是记录我组装这三件套的完整过程每一步怎么设计、为什么这么设计、中间踩过哪些坑都会讲清楚。如果你正在用大模型 API 做 Agent 或者自动化工作流这篇应该能帮你少走不少弯路。1. 为什么 Tool、Context 和输出合约必须一起设计很多人一开始都会犯同一个错先把工具函数写出来然后让模型在对话里“自由发挥”最后靠正则表达式去解析模型的回答。我在 Pi 上第一次这么做的时候效果惨不忍睹——工具函数倒是能跑但模型要么根本不知道该调它要么给出的参数牛头不对马嘴要么工具结果返回了模型也用不明白。1.1 工具能跑不等于模型能用工具函数本身是给 Python 跑的但模型只知道它的文本描述。模型看到的并不是你的函数代码而是你在系统提示词或者工具定义里写出来的“说明书”。如果说明书写得含糊或者参数 schema 设计得随随便便模型就只能连蒙带猜。比如我早期给 Pi 写过一个获取会议室的工具description 写的是“查询会议室空闲情况”参数里有 start_time、end_time、room_id。看起来没问题但模型在实际调用时经常只传一个 start_time不传 end_time或者把 room_id 传成一个房间名字符串而不是数字编号。问题不在模型而在我的工具定义没有告诉模型这两个时间参数必须成对出现、room_id 具体有哪些可选值。模型是在做“补全”它只能根据你提供的文字和结构去猜最合理的调用方式。工具定义不严谨模型就会用它的想象力替你补漏。所以 Tool 的组装第一步不是写函数而是把函数翻译成模型能精确理解的那份“说明书”。1.2 执行结果进不了 Context工具等于白调工具调用成功后还有一个更隐蔽的坑模型生成回答时根本看不到工具执行结果。大模型的上下文就是消息列表如果你只是把工具函数跑完拿返回值在 Python 里打印了一下然后让模型继续生成回复模型其实是在“盲答”。我最早以为只要工具结果出现在终端里模型自己就会知道。后来发现根本不是这么回事。模型能看到的全部内容都在 Context 里。工具结果必须重新写回消息列表放在一个模型能读到的统一位置而且要明确标注这是工具输出。否则会出现一种很滑稽的现象模型明明说“好的我帮你查一下”然后工具也确实跑完了但接下来模型开始自己瞎编数据——因为它根本不知道工具返回了什么。这就是 Tool、Context、输出合约要一起设计的原因。Tool 决定“能做什么”Context 决定“模型知道什么”输出合约决定“回答长什么样”。三者是一条水流任何一环断了整条链路都瘫痪。1.3 组装的第一原则先定数据流再写具体代码我在推倒重来之后给自己定了几条铁律后面所有设计都围绕这些原则展开工具的 schema 描述必须出现在每次请求的上下文中每次对话都带上不能只在第一轮带。工具执行结果必须以结构化的形式写回上下文并明确区分“这是工具输出的 JSON”和“这是模型自己的思考”。模型产出必须走输出合约不仅约束最终回复的格式连中间的工具调用参数也要校验。一旦模型调用工具就强制进入“模型→工具→模型”的循环而不是让模型一次性同时干推理和回答。这几条规则开始看着笨重但实际跑起来后发现它们把“不确定性”锁住了很大一部分。模型的不确定性永远在但你可以通过设计把不确定性的影响范围压缩到一个可控的角落。后面每一步都是在填充这几条原则的细节。2. Tool 层组装从“模型看得懂”到“系统跑得通”Tool 层是整个 Pi 的地基。这一步做得越扎实后面 Context 和输出合约就越省心。我在这一阶段主要做了四件事写一份合格的工具描述、在函数入口做参数强校验、设计结构化的错误返回、最后保持工具函数本身的无状态性。2.1 工具描述不是写给人看的功能说明而是写给模型的调用手册我后来把工具描述想象成“给一个新同事写的工单处理 SOP”。光说“处理工单”没用要写清楚什么条件下用这个工具、参数分别是什么意思、参数之间有什么约束、有没有默认值、什么情况下会报错。以 Pi 里的一个简单工具为例查询天气{ type: function, function: { name: get_weather, description: 查询指定城市在指定日期的天气情况。当用户提到城市和日期且需要天气信息时使用。如果用户没给日期默认使用今天。, parameters: { type: object, properties: { city: { type: string, description: 城市中文名例如北京、上海、广州。必须是中国城市的中文名称。 }, date: { type: string, description: 查询日期格式为YYYY-MM-DD。如果用户没有指定日期不要填写由系统默认处理。 } }, required: [city] } } }这里有几个细节值得细说。description里我明确写了“当用户提到城市和日期且需要天气信息时使用”这是给模型的触发条件如果不写模型可能在闲聊时也强行调用工具。city的描述里写了“必须是中国城市的中文名称”这是防止模型把“北京”翻译成 “Beijing” 塞进去。date的描述里写了“如果用户没有指定日期不要填写由系统默认处理”这比在代码里处理缺失日期更有效——模型会把 missing 状态留给你而不是自己脑补一个未来日期。每一个描述都不是废话都是在降低模型犯错的概率。2.2 参数强校验入口处拦住非法调用模型调用工具时返回的参数本质上只是“一段符合 JSON 格式的文本”。你无法保证它一定符合你的 schema。我见过模型把数字参数写成字符串、把日期写成“明天”、把枚举值写成英文的情况。所以在工具函数入口第一件事就是做强校验而不是直接丢给函数体。def safe_call_tool(name: str, arguments: dict) - dict: schema TOOL_SCHEMAS[name] try: validated validate_arguments(schema, arguments) except ValidationError as e: return { status: error, error_type: invalid_arguments, message: f参数校验失败: {e}, hint: 请根据参数说明重新生成合法的参数 } return execute_tool(name, validated)这里的validate_arguments你可以用任何 JSON Schema 校验库或者直接用 Pydantic 定义强类型模型。关键是校验失败的返回值也有固定结构方便后面模型自己根据错误信息修正参数重新调用。这一步做下来工具函数内部就永远不会碰到“参数类型不对”的崩溃所有异常都被挡在入口之外。2.3 工具报错让模型去解释错误好过硬编码兜底文案工具执行时还可能抛异常比如网络不通、服务返回 500、数据不存在。我之前习惯在工具里 try-except 然后直接返回一句“查询失败请稍后再试”。后来发现这样很糟——模型根本不知道发生了什么用户问“为什么查不了”模型只能继续编。更好的做法是把错误结构化返回并且让模型看到错误原因{ status: error, error_type: external_api_error, message: 天气服务连接超时, hint: 建议让用户稍后再试或者询问是否切换查询昨天/明天的天气 }把这段 JSON 写回上下文后模型生成回复时就会参考hint来组织语言告诉用户具体的失败原因和替代方案。这比任何预先写死的提示词都自然而且每个工具的错误处理逻辑可以共用一套模式。核心思路是错误信息也是给模型看的上下文不是给用户看的最终文案。最终文案让模型去组织但组织的方向和边界由 hint 来约束。2.4 工具函数设计的三个心得工具函数本身不要写复杂业务逻辑职责越单一越好。比如“获取工单列表”和“获取工单详情”就拆成两个工具不要写成一个工具靠参数区分。原因有二一是模型如果只看到一个大而全的工具它可能搞不清该传什么参数组合二是工具拆细之后描述更精确模型调用成功率明显上升。还有工具函数的参数类型能少用array就少用。模型在生成数组参数时经常把类型搞错比如把[a,b]写成a,b。如果非要数组description 里一定要给一个明确的格式示例。我自己的经验是能用 string 解决的绝不用 array能用单个对象的绝不用嵌套数组。最后所有的工具函数都做成无状态的执行结果完全由输入决定。这不仅是工程上的好习惯对模型也更友好——对于一个无状态的工具模型不需要去记忆“上一次调用后发生了什么变化”每次调用都是一次干净的查询或操作。3. Context 组装给模型一张不会被弄乱的工作台Context 就是模型的工作台。它上面摆着系统提示词、历史对话、工具描述、工具结果所有模型能“看到”的信息都必须在这里。组装 Context 的难点不是把东西塞进去而是要让模型清楚分辨每一块信息的角色和边界同时控制住上下文长度。3.1 系统提示词除了人设还要有环境变量和运行时信息我早先的系统提示词就是一段人设“你是 Pi一个智能助手……”后来发现不够。模型需要知道大量运行时信息才能正确决策。比如当前真实日期和时间模型不主动知道“今天”是哪天。当前环境有什么工具可用即便工具列表在接口参数里传了系统提示里再列一版摘要模型调用效果往往更好。运行模式是“工具编排模式”还是“纯对话模式”。输出必须遵循的合约要求包括不允许输出的内容类型。我把这些信息做成了一个render_system_prompt()函数动态拼进系统提示词里。日期用代码实时生成确保每次请求都是最新的工具摘要也从工具注册表里自动生成避免手写两份不一致的清单。拼完之后的系统提示词大致长这样你是 Pi一个本地搭建的智能助手基于大模型接口运行。 当前日期2025-04-18 可用工具get_weather查询天气、get_meeting_room查询会议室空闲情况、create_todo创建待办事项。 使用规则 1. 当用户需求涉及可用工具功能时必须调用工具不要直接编造答案。 2. 调用工具后必须等待工具结果返回再基于结果组织最终回复。 3. 最终回复必须以符合输出合约的 JSON 格式输出合约定义见下文。模型读完这一屏内容后相当于拿到了一份“开机指南”在错误的方向上狂奔的概率会大幅下降。3.2 消息列表的正确顺序用户消息、工具结果、系统边界的摆放Context 组装的核心是消息列表。我采用的标准结构是messages [ {role: system, content: system_prompt}, *conversation_history, # 历史对话 {role: user, content: current_user_input}, ]模型第一次给出工具调用后要把工具结果作为一个新的消息追加进去然后再交给模型生成最终回复。这一步乍一看简单但里面有个魔鬼细节工具结果必须放在一个明确的位置不能和历史对话混在一起。Pi 的做法是每轮工具调用完成后往消息列表追加两条消息。第一条是assistant角色内容是一个简短的“我将调用工具 get_weather”第二条是tool角色内容是工具执行的原始 JSON 结果。这里的顺序必须是“模型声明调用工具→工具返回结果”模型才能在这个基础上继续推理。messages [ {role: assistant, content: f我需要调用 {tool_name} 来获取信息。}, {role: tool, content: tool_result_json}, ] # 然后再让模型基于现有上下文生成最终回复 final_response model.chat(messages)如果跳过第一步的 assistant 声明直接把工具结果塞进上下文有些模型会分不清这段 JSON 是谁说的从而把工具结果误认为用户输入。我踩过这个坑后来拆成两条消息就稳定多了。这个顺序本质上是在模仿人类协作的对话结构A 说“我去查一下”B 递过来结果A 再综合信息给结论。模型是在做模式复现结构越接近它的训练语料表现就越自然。3.3 上下文长度与截断策略不要无脑堆历史保住关键信息Context 是所有信息的载体但长度是有限的。对话一长历史消息就会把 token 撑满工具结果和系统提示被挤到最后模型容易“忘掉”前面的内容。Pi 里我采用的策略是“优先级分层”系统提示词和工具结果永远保留历史对话按权重截断。询问类工具的即时结果必须留下因为模型还要基于它生成回复历史寒暄可以压成摘要“用户上上轮问了很多但和当前任务无关的内容”直接丢弃。我在实现时做了一个简单的滑动窗口系统提示词固定保留。最近 3 轮完整对话完整保留。更早的历史压缩成一段 200 字以内的摘要由模型通过一次单独的 summarize 调用生成。当前工具结果与相关工具调用声明固定保留。“摘要历史”这步单独会消耗一次模型调用但能显著提升长会话场景下的效果。如果你的场景不做非常长的多轮对话可以先把这步省掉只在 token 超限时触发。3.4 一个容易忽略的坑旧工具结果污染新对话组装 Context 时最隐蔽的 bug 是过期工具结果残留。比如用户第一轮问“北京天气”工具返回了数据模型正常回答了。第二轮用户问“那上海呢”如果你的消息列表里还堆着第一轮的天气 JSON模型可能会犯糊涂把北京的数据和上海的问题混在一起或者干脆拿旧结果硬答。我加了一条铁律每次用户发起新一轮对话时如果上一轮的工具结果已经用于生成最终回复就把它从 Context 中移出只保留最终回答作为历史。只有当前正在处理的那一轮工具结果才保留在上下文中。这个规则简单粗暴但非常有效。def build_messages(new_user_input: str) - list: messages [{role: system, content: system_prompt}] for item in cleaned_history: # 已剔除已消费的工具结果 messages.append(item) messages.append({role: user, content: new_user_input}) return messages配合这个清理逻辑我还会在日志里记录每次组装的 Context 快照出现问题可以直接回溯是哪一条旧消息影响了模型。4. 输出合约让模型按格式说话用代码兜底校验上下文组装完之后模型的输出就成了唯一的“产品”。如果模型输出的是一堆散文下游没法分析用户也拿不到结构化结果。输出合约就是在这里立规矩的它是一份模型必须遵循的输出 JSON 格式约束。4.1 输出合约定义终极回复的结构化模板Pi 的合约里定义了一个统一的外层结构{ fulfillment: { speech: 直接面向用户的话, data: {}, intent: 系统识别到的用户意图分类 errors: [] } }speech是模型真正要展示给用户的那句话。data是结构化数据比如查到的天气数据、会议室列表供前端渲染或下游流程使用。intent是意图分类例如weather_query、meeting_room_booking、general_chat。errors用于存放错误信息正常回答时为空数组。这个结构看着直白但好处很大。模型被要求把所有思考成果都装进这层合约用户看到的speech、系统消费的data、逻辑分支用的intent就被自然分开了。不会出现“模型的解释文本里夹着一份 JSON 数据”这种脏局面。4.2 JSON Schema 约束让模型直接在采样阶段收敛格式现在的模型服务商基本都支持响应格式强约束通过 JSON Schema 锁定输出结构。严格语法校验模式下模型在生成 JSON 时每一步采样都会做语法检查从根上避免了“JSON 截断”“逗号缺失”这类低级错误。Pi 里用的 schema 大致长这样{ name: fulfillment, strict: true, schema: { type: object, properties: { fulfillment: { type: object, properties: { speech: {type: string}, data: {type: object}, intent: {type: string, enum: [weather_query, meeting_room_booking, create_todo, general_chat]}, errors: {type: array, items: {type: string}} }, required: [speech, data, intent, errors], additionalProperties: false } }, required: [fulfillment], additionalProperties: false } }strict模式加上additionalProperties: false效果就是把模型的输出锁在一个严格的 JSON 容器里。模型想输出合约之外的内容在采样阶段就会被拒掉。这一步直接改变了模型生成结果的行为模式比事后解析 JSON 再纠错要稳一个量级。4.3 少样本示例schema 管格式示例管语义光有 schema 还是不够。schema 只约束了“字段的类型和结构”但没有约束“字段应该填什么粒度的内容”。比如speech字段模型知道必须是字符串但不知道应该填 10 字以内的简洁回复还是填一段 200 字的话术。这时候少样本示例就很有用了。我在输出合约的描述旁边附带了一个示例输出{ fulfillment: { speech: 北京今天晴气温 18-28 度东南风 3 级适合出门。, data: {city: 北京, weather: 晴, temp_min: 18, temp_max: 28}, intent: weather_query, errors: [] } }模型看到这个示例后就知道speech应该用自然的人话data里放结构化数值intent分层不能乱写。尤其是data字段里放什么粒度的信息必须有示例。我试过不给示例模型会把整个回答文本复制进data导致下游解析很痛苦。4.4 校验与重试机制不能把宝全押在模型身上即使 schema 强制了格式模型仍然可能输出语义上不符合合约的内容。比如errors数组为空但speech里却告诉用户“出错了”。这属于语义层面的违约语法校验查不出来。所以输出合约的最后一道防线是代码层校验def validate_and_repair(fulfillment: dict) - dict: try: FulfillmentModel.model_validate(fulfillment) return fulfillment except ValidationError: # 把校验错误塞回上下文让模型自己修复 repair_prompt f你的输出不满足要求{e}请修复后重新输出。 messages.append({role: user, content: repair_prompt}) return None # 触发重试这里的逻辑是第一次输出不通过校验时不直接报错而是把校验失败的详细信息作为一条新消息追加到上下文让模型基于错误自己修正。实践证明模型看到具体的校验错误后第二次修正的成功率很高。如果连续两次失败再落回拒绝回答的兜底分支。这样设计的原因很简单让模型自己修比你在外面硬改它的输出更可靠。你硬改 JSON 字段改出来的结果模型自己都不知道后面的对话逻辑会乱套。给模型一次“自我纠错”的机会往往代价很低收益却不小。4.5 输出合约的边界字段命名要对模型友好输出合约的字段名最好和模型平时见到的自然语言表达一致。比如speech比utterance更好errors比faults更好。不是你对英文不熟而是模型在训练语料里更常遇到speech这类词它理解起来更轻松生成时也更顺。同理intent的枚举值也要选模型容易分类的词不要在weather_query和weather_inquiry之间摇摆不定选一个就行。如果业务里需要非常复杂的输出结构我的建议是分步输出先让模型输出核心字段再通过一次工具调用把扩展字段补全而不是一次性要求模型输出一个巨型 JSON。模型生成的 JSON 越长准确率越低。短小聚焦的合约效果远好于大而全的合约。5. 三件套闭环把 Tool、Context、输出合约焊成一条完整的链路三件套分开讲完之后最关键的一步是组装闭环。Tool 是脚Context 是身体输出合约是嘴单靠任何一部分都跑不起来。这一节就是 Pi 完整处理“一个用户请求”时的数据流全貌以及我为了让它稳定运行加的各种保险丝。5.1 一次完整调用的八步链路Pi 的主循环这么走接收用户输入调用build_messages()生成初始消息列表系统提示词、清理后的历史、当前用户消息全部就位。把消息列表连同工具 schema 列表、输出合约一起提交给模型服务接口。模型返回两种可能之一直接生成满足输出合约的最终回复或返回一个工具调用请求。如果是工具调用请求先校验工具名是否存在、参数是否符合 schema失败就返回结构化错误。参数合法则执行真实工具函数拿到工具的原始 JSON 结果。把“模型声明调用工具”的消息和“工具结果”的消息追加进消息列表再回到第 2 步。模型基于工具结果生成最终回复进入输出合约校验。校验通过后把speech返回给用户把data交给下游把整轮消息归档进历史。这个循环很朴素但每一步都踩在前面设计好的轨道上。工具调用出错时走的是“错误结果写回上下文→模型自纠错→重试”的路径而不是直接把异常抛给用户。输出合约不通过时走的是“校验错误回填→模型重新生成”的路径而不是把半成品 JSON 硬拼成回复。5.2 循环熔断防止模型在工具调用里死循环模型在工具调用环节有一个典型毛病它会连续多次返回相同的工具调用请求尤其在工具报错后。比如第一次调用天气工具失败返回了错误 JSON模型看到后非但不修正反而再生成一次一模一样的调用然后又失败无限循环。我加了两道保险最大调用次数限制单轮用户请求中模型最多调用工具 4 次。超过之后直接放弃工具路径强制生成一个带错误的最终回复。重复调用检测如果模型连续两次请求同一个工具且参数完全相同就判定为“工具调用卡死”中断循环并提示它换一种方式。这个熔断机制非常必要。没有这两个限制前Pi 曾出现过一次“调用会议室查询工具 9 次”的恐怖经历因为工具返回不可用模型就一直尝试白白烧了大量 token。锁住循环次数之后这类问题再没有出现过。5.3 可观测性没有完整日志组装就是盲人摸象组装三件套的调试期日志是最重要的工具。我每轮请求都会记录以下信息Context 快照最终发给模型的消息列表全文。Token 消耗输入、输出、单轮总计。模型返回原文包括工具调用请求和最终回复未经过任何后处理。校验结果参数校验是否通过、输出合约校验是否通过。工具执行耗时和结果摘要。有一次 Pi 回答驴唇不对马嘴我查了半天代码没找到问题最后翻日志发现上上轮的工具结果没有被清理混进了当前轮次的上下文。如果没有 Context 快照日志这个问题可能永远排查不出来。日志要记到“可重放”的程度——能根据日志完整还原当时的模型输入和输出调试效率直接翻倍。5.4 边界情况处理工具不存在、结果超长、并行调用还有几个边界情况我在组装时做了特殊处理。模型偶尔会“编造”一个根本不存在的工具名。这种情况直接返回结构化错误提示“该工具不存在以下是可用工具列表”让模型重新选择。工具返回结果可能非常长比如查询出来 500 条工单记录。把完整结果写回上下文既费 token 又干扰模型注意力。我做了个截断策略超出 2000 字符的部分直接截断并在结果末尾追加一行“结果过长已截断仅展示前 N 条”。模型如果需要更多数据会主动提出分页查询或缩小条件。多个工具并行调用的情况Pi 暂时不做。一次只允许模型返回一个工具调用请求。并行调用虽然能省时间但会让 Context 的组装复杂度大幅上升而且不同工具结果之间可能会互相干扰。从稳定性和可维护性角度看串行调用是性价比最高的选择。等日志追踪和错误恢复机制更成熟之后再考虑并行化。组装到这步Pi 才算真正跑通了“用大模型做 Agent”的第一版闭环。后面要做的事情还有很多但这三块地基已经焊在一起不再是一堆散装的零件。我在实际使用中的一个体会是这三件事最好从第一天就捆在一起考虑。分开做的话你很快会陷入“工具能跑但模型不用模型用了但回答没法解析回答能解析但数据进不了下一步”的连环坑。先把数据流的形状定清楚再去填每一块的细节整个系统才能真正转起来。

相关新闻

perf kmem

perf kmem

perf kmem 获取内存分配信息的核心,是依赖内核预设的 tracepoint(跟踪点)。它本身并不直接“读内存”,而是作为一个用户态消费者,去监听内核在内存分配/释放时主动“广播”出来的事件。原理:监听内核的“广…

2026/10/14 10:29:53 阅读更多 →
27B模型后训练实战:三大基准突破90分与思考链压缩

27B模型后训练实战:三大基准突破90分与思考链压缩

前前后后折腾了两个月,手上这个27B模型的后训练总算收尾了。三个核心基准——GPQA、MMLU、LCB全部站上90分,同时把基座模型那套动不动上千字的思考链压缩了大半。发布版本已经挂出去,这篇文章就把整个流程拆开写一遍,从评估指标到…

2026/10/14 10:29:53 阅读更多 →
Qwen3.8 27B后训练实战:三大基准过90,思考量压缩70%

Qwen3.8 27B后训练实战:三大基准过90,思考量压缩70%

Qwen3.8 27B的后训练项目,到今天算是彻底收尾了。写这篇不是为了例行汇报,而是因为这一版的结果确实有点超出我自己的预期:GPQA、MMLU和LCB三个评测集全部冲过90分,同时平均思考量压到了原版模型的四成不到。对于一个27B规模的开源…

2026/10/14 10:29:53 阅读更多 →

最新新闻

数据库安全加固实战:五大数据库风险排查与加固指南

数据库安全加固实战:五大数据库风险排查与加固指南

简介:一份面向数据库运维与安全管理技术人员的数据库安全加固手册,围绕 MySQL、Oracle、SQL Server、PostgreSQL、Redis 五种主流数据库,逐项梳理用户与密码配置、权限管理、通信加密、日志审计、文件权限等关键安全控制点,并给出…

2026/10/14 11:18:26 阅读更多 →
面向Agent的互联网:资源接口的设计与改造实践

面向Agent的互联网:资源接口的设计与改造实践

1. 从“人看网页”到“Agent 读接口”,互联网发生了什么变化 1.1 先搞清楚“面向 Agent 的互联网”到底在说什么 过去十几年我们谈互联网,默认的使用者是“人”。人在浏览器里输入网址、滚动页面、辨认按钮、点击链接,这整套行为都建立在人类…

2026/10/14 11:18:26 阅读更多 →
开源客户端省Token实战:上下文管理、模型路由与缓存优化

开源客户端省Token实战:上下文管理、模型路由与缓存优化

前阵子一位朋友跟我抱怨,他给团队搭的问答机器人,每天只是几十个人问问题,月底账单却高得离谱。我帮他检查了一遍调用链路,问题很明显:客户端一直用官方默认配置,上下文窗口拉满,系统提示词写了…

2026/10/14 11:18:26 阅读更多 →
OpenTiny开源项目:从组件库到智能前端生态的演进

OpenTiny开源项目:从组件库到智能前端生态的演进

1. OpenTiny开源项目三年发展全景回顾 作为国内企业级前端开源领域的标杆项目,OpenTiny在过去三年间完成了从单一组件库到完整前端开发生态体系的蜕变。这个由华为云前端团队主导的开源项目,最初只是为解决内部业务需求而诞生的技术方案,如今…

2026/10/14 11:18:26 阅读更多 →
超临界二氧化碳布雷顿简单循环MATLAB计算程序:建模思路与工程验证指南

超临界二氧化碳布雷顿简单循环MATLAB计算程序:建模思路与工程验证指南

简介:面向能源动力领域的技术人员、科研人员及相关专业学生,基于 MATLAB 的超临界二氧化碳布雷顿简单循环计算程序,能替代繁琐的人工手算,帮助使用者快速完成热力状态参数求解与循环性能评估。压缩包内包含 2 个 m 文件&#xff0…

2026/10/14 11:18:26 阅读更多 →
cmux实战:将AI Coding的Agent、浏览器和终端统一编排进同一会话

cmux实战:将AI Coding的Agent、浏览器和终端统一编排进同一会话

干 AI Coding 最烦的事情,往往不是模型给错了答案,而是窗口开得太多。左边一个 Agent 在跑分析,右边浏览器开着开发预览,底下还有四五个终端在编译、跑测试、看日志……我一度以为是自己不够专注,后来才意识到是工具管…

2026/10/14 11:17:25 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →