大模型工具调用实战:Function Calling与Agent Harness Engineering

上个月我在做一款带工具的对话助手,核心需求是让模型在需要时能调用天气查询、日程管理这类外部能力。最开始建模的时候,我用了最省事的方案:在系统提示词里把JSON格式写得明明白白,让模型自己输出动作和参数,然后在代码里解析。结果整个联调阶段都在填自然语言解析的坑——模型有时把JSON包在Markdown代码块里,有时在JSON前面多加一句"好的,我来为您查询",有时把参数名从双引号改成单引号,最离谱的一次它把整个JSON对象的键值对顺序全打乱了,我的正则匹配直接瘫痪。

后来换成模型接口原生支持的Function Calling机制,才真正体会到"专业的事要交给专业的机制去做"这句话的分量。这篇文章想以一个踩坑者而不是理论家的身份,把Function Calling从表层API调用到系统集成再到工程化落地完整拆一遍,顺带聊聊标题里那个听起来有点唬人的概念:AI Agent Harness Engineering——按我的理解,它就是那个把模型大脑和外部工具手脚衔接起来的“传动系统”。

1. 从一次翻车的JSON手写解析,透视Function Calling的本质

1.1 没有Function Calling的时代,Prompt输出JSON有多不靠谱

先还原一下我最初的做法。面对“北京今天需要带伞吗”这种问题,我会在系统提示词里写:

如果需要查询天气,请输出以下JSON格式: {"tool": "get_weather", "params": {"city": "北京"}} 不要输出其他内容。

这段提示词在Demo场景下能跑通,但真实请求一多就原形毕露。模型毕竟是语言模型,它终归倾向于“说人话”,而不是做严格的格式输出。我实际遇到的典型情况有这么几类:

  • 在JSON外层包Markdown代码块,需要先用正则剥离
  • 输出里混入解释性文字,例如“根据您的需求,我查询了天气信息:”
  • 键名被改写,比如把params变成了parameters
  • 单引号替换双引号,null被写成None,布尔值写成字符串

每一类我都得写对应的解析逻辑和重试策略。最让人崩溃的是,模型升级之后行为还会变——以前不包代码块的,升级后突然开始包了。你的解析代码永远在追赶模型的行为变化。

1.2 Function Calling接口的真实工作方式

功能调用机制和上述做法有本质区别:它不是要求模型在自然语言文本里“附带”一段JSON,而是让模型在解码阶段就被引导去生成一个结构化的工具调用请求。这个请求会作为一个独立的、带有固定字段的消息返回,不掺杂任何自然语言修饰。

以常见的接口格式为例,模型返回的消息里会多出一个tool_calls数组,每个元素大概长这样:

{ "id": "call_abc123", "type": "function", "function": { "name": "get_weather", "arguments": "{\"city\": \"北京\"}" } }

注意arguments依旧是一个JSON字符串,需要你自己解析。但它和Prompt手写JSON有本质区别:模型在arguments里生成的内容更加规范,不会出现“好的,我来查询”这种废话,也不会把双引号换成单引号。原因在于接口层在训练和推理时都针对结构化输出做了对齐,模型已经形成了“这个位置就应该输出合法JSON”的条件反射。

如果你以为这个机制是万无一失的,那又掉进另一个坑了。实际体验下来,它只是把“从自然语言里猜JSON”的问题率降到了可接受范围,而不是降到了零。参数值幻觉、调用不存在的工具名、嵌套对象残缺,这些问题依然存在,我在第5章会专门展开。

可以把三种方案做个直观对比:

方案输出稳定性可控性解析成本适用场景
Prompt手写JSON极差,随模型版本波动低高,需要大量正则和重试轻量体验、内部原型
JSON Mode / Output Schema较好,但只保证格式中中,仍需二次校验需要纯结构化输出、不涉及工具选择
Function Calling好,工具调用是原生能力高,可选指定工具低,字段固定Agent系统、多工具场景、复杂任务

2. Harness Engineering:模型、工具与执行循环如何拧成一股绳

2.1 “手脚”之外,更重要的是传动系统

Function Calling本身只是给模型开了一扇“可以调用工具”的门。但要让Agent真正稳定地完成一连串任务,你需要围绕这个功能搭建一整套工程机制,这套机制就是标题里说的Harness Engineering。

打个比方:LLM是“大脑”,负责理解意图和做决策;工具是“手和脚”,负责触碰外部世界;而Harness Engineering是“神经和骨骼系统”,负责把大脑的命令准确无误地传导到手脚,再把手脚感知到的信息传回大脑。没有这套传动系统,大脑再聪明,手脚也是瘫着的。

一个最简Agent系统的循环长这样:

  1. 用户输入 → 系统提示词 + 工具定义列表 → 模型
  2. 模型推理,产出结论或调用请求
  3. 如果有调用请求 → 代码解析请求 → 执行对应工具函数 → 拿到结果
  4. 把工具结果作为新消息回填给模型
  5. 模型收到结果后继续推理,可能再发起新一轮调用,直到给出最终答复

这个看似简单的循环里,每一步都有陷阱:工具结果应该以什么角色消息回传?tool_call_id对不上会怎样?模型连续调用时上下文怎么维护?如果只把Function Calling当作“一个能让模型输出JSON的API”来用,遇到这些问题一定会手足无措。

2.2 一个最小Harness的代码骨架

我把自己项目里的核心循环简化成下面这段,可以作为起步参考。假设你用某个兼容ChatCompletion风格的SDK,并已经初始化好了客户端:

import json MAX_ROUNDS = 5 TOOL_REGISTRY = {} def register_tool(name, schema): def decorator(func): TOOL_REGISTRY[name] = {"func": func, "schema": schema} return func return decorator @register_tool("get_weather", { "type": "function", "function": { "name": "get_weather", "description": "查询指定城市的实时天气信息", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "城市名,例如:北京、上海"} }, "required": ["city"] } } }) def get_weather(city: str): # 这里替换成真实天气API调用 return {"city": city, "temp": 26, "condition": "多云"} def run_agent(user_message, messages=None): messages = messages or [] messages.append({"role": "user", "content": user_message}) for _ in range(MAX_ROUNDS): resp = client.chat.completions.create( model="your-model-name", messages=messages, tools=[entry["schema"] for entry in TOOL_REGISTRY.values()], tool_choice="auto" ) msg = resp.choices[0].message if not getattr(msg, "tool_calls", None): return msg.content messages.append(msg) # 把模型这条带着tool_calls的消息加入对话 for call in msg.tool_calls: fn_name = call.function.name if fn_name not in TOOL_REGISTRY: # 模型可能生成不存在的工具名,必须兜底 messages.append({ "role": "tool", "tool_call_id": call.id, "content": json.dumps({"error": f"unknown tool: {fn_name}"}) }) continue args = json.loads(call.function.arguments) result = TOOL_REGISTRY[fn_name]["func"](**args) messages.append({ "role": "tool", "tool_call_id": call.id, "content": json.dumps(result, ensure_ascii=False) }) raise RuntimeError("agent loop exceeded max rounds")

有几个细节值得强调。第一,messages.append(msg)这一步不能省,否则模型丢失了它自己刚才提出的调用请求,后续推理会“断片”。第二,工具执行结果必须以role="tool"回传,而且要带上对应的tool_call_id,接口层靠这个字段把结果和请求配对;tool_call_id对不上的话,平台会直接报错,这个错误在五花八门的报错里算是比较好排查的。第三,MAX_ROUNDS必须设置,否则遇到极端情况,模型可能会无限循环调用工具。

3. 工具Schema的设计细节:模型“听话”与否,七成由你写的描述决定

3.1 description不是写给人看的,是写给模型看的

很多人写工具定义时,description就一句话:“查询天气”“获取股票信息”“创建日程”。这太吝啬了。模型没有机会“试用”你的工具,它对工具的全部理解都来自这段描述。描述写得太短,模型就会在拿不准时乱用一通。

我印象很深的一个反例,是项目里有个同事写的一个“query_stock”工具,description只有四个字:“查询股票”。结果用户问“最近黄金价格怎么样”,模型也去调了这个工具,返回一堆毫无意义的数据。后续排查时我们才意识到,模型根本不知道这个工具只能查股票、不能查黄金。

我自己现在写description有一条原则:写清楚“这个工具是干什么的”“在什么情况下使用”“在什么情况下绝对不能使用”。比如改成下面这样:

{ "name": "query_stock", "description": "查询A股或港股的实时股价、涨跌幅和成交量。当用户询问股票行情、股价走势时使用此工具。当用户询问基金、黄金、期货等其他资产时,请勿调用此工具,直接告知用户暂不支持。", "parameters": { "type": "object", "properties": { "code": { "type": "string", "description": "股票代码:A股为6位数字(如600519),港股为5位数字(如00700)。" }, "market": { "type": "string", "enum": ["A", "HK"], "description": "市场类型:A股填A,港股填HK。可根据代码位数判断,不确定时以用户指令为准。" } }, "required": ["code"] } }

多写两句话,模型的行为就会完全不同。给模型的“说明书”写得越清楚,它在真实场景里的选择就越稳健。

3.2 参数Schema:陷阱重灾区

参数定义是另一个容易翻车的地方。我把踩过的坑整理成几条经验:

第一,required字段能少则少。模型面对缺失参数时,不会像人一样说“信息不足,请补充”,它倾向于自己“脑补”一个值。比如工具需要city和date,date不是必填时,用户只说了城市,模型很可能自己编一个“今天”塞进去。这看起来没问题,但如果你的业务对时间敏感,就会引入严重错误。所以,只有绝对必要的字段才放进required,可选字段在description里明确标注“缺省时使用XXX”。

第二,能用enum就用enum。如果某个字段只有几种合法取值,一定要写枚举。比如状态字段,合法值是created和cancelled,你不写enum,模型就敢给你生成一个completed;写了enum,虽然不能100%杜绝,但至少模型在受限的选项里选择,出错的概率会低很多。

第三,参数description要写单位、边界和默认值。我遇到过模型把“温度单位”默认理解成华氏度的场景,因为description里就写了“温度”两个字。后来改成“温度数值,单位为摄氏度,例如25”,问题就消失了。参数的单位、格式、取值范围、默认值,这些都是描述里必须交代的信息。

第四,尽量用扁平参数,少用深层嵌套。模型对深层嵌套结构里的字段生成能力明显弱于扁平结构。有时候你会倾向把工具的入参设计成一个复杂对象,比如:

{ "user": {"name": "", "age": 0}, "preferences": {"notify": true} }

但实测下来,嵌套层级越多,模型漏字段、填错类型的概率就越高。我的建议是:把嵌套结构打平,用user_name、user_age、notify_user这样的扁平字段替代。看起来参数数量变多了,但模型生成的准确性会明显提升。

工具Schema设计这块,本质上是在给模型“布置任务”。你布置得越清晰,模型的完成度就越高;你指望模型自己悟,它就用自己的想象力去填坑。

4. 多轮调用、并行调用与Agent Loop的实操拆解

4.1 模型自己会“打组合拳”:连续多轮调用

当工具数量达到三四个以后,模型往往会主动发起多轮工具调用来完成一个复合任务。举个我在项目中测试过的例子:用户说“帮我约明天下午3点和合作方的视频会议,顺便订一间能坐八个人的会议室”。

这个任务其实是两步:先查日程看时间是否空闲,再创建会议并预定会议室。模型在Function Calling机制下会自动这样处理:

  1. 第一轮调用check_schedule,传入明天15:00,拿到空闲状态
  2. 第二轮调用create_event,传入会议主题、时间、参与人
  3. 第三轮调用book_room,传入人数和时段

每一轮调用结束后,模型都会看到工具返回的结果,然后基于最新上下文继续决策。这意味着你的Agent Loop必须正确维护对话历史:模型的tool_calls消息、工具的结果消息、模型后续的推理消息,全部按顺序追加进messages。任何一个环节缺失,循环就会断。

实际体验中,模型是否选择“打组合拳”,和工具描述、任务复杂度都有关系。任务拆解成多个步骤时,模型更倾向逐步调用;如果工具描述写得太抽象,模型也可能一步到位强行塞进单次调用里,导致参数缺失。

4.2 并行调用:能省时间,但要留意隐藏依赖

部分平台的接口支持一次返回多个tool_calls。比如同时查天气和查日历这两件事没有依赖关系,模型就可以把两个调用请求放在同一个响应里,你的代码并行执行两个工具函数,再把结果一次性回传。

但这里有个隐蔽的坑:模型并不知道你的工具之间存在数据依赖。比如订单系统里,“创建订单”和“支付订单”在业务上必须顺序执行,先有订单号才能发起支付。但模型可能把这两个工具误认为可以并行,同时发出两个调用请求,然后你的代码在支付时发现订单号还没生成,直接抛异常。

我的经验是:凡是存在明确先后依赖关系的一组操作,不要拆成多个工具让模型自己编排,而是设计成一个状态机工具。比如,把create_order和pay_order合并成一个create_and_pay_order工具,把依赖关系封装在工具函数内部。模型只需要做一次调用,返回结果天然是正确顺序。这相当于把不该模型操心的编排逻辑移到了你的确定性代码里,可靠性会大幅提升。

另外,并行调用时还要注意工具函数的线程安全性。如果你的工具函数里有共享状态、锁或计数器,并发执行时可能出现数据竞争。我自己就遇到过两个工具同时写一个全局缓存,把缓存内容互相覆盖的情况。给工具函数加个互斥锁,或者干脆把工具函数设计成无状态的,能省掉很多麻烦。

5. 模型会撒谎、会绕圈:工具调用中最常见的四个失控场景

5.1 参数幻觉:模型会编造不存在的取值

问题场景:工具定义里明确写了一个字段的enum只有low和high两个取值,模型生成arguments时,直接给了一个urgent。这种参数值幻觉,在字段定义越宽松时越容易出现。

应对方式是在执行工具前加一层校验。我会用JSON Schema的校验库对模型的arguments做一次完整检验,校验不通过就返回错误信息给模型,让它重新生成。这层校验不是可选项,而是Agent系统的安全底线。模型输出的内容本质上是一个“预测结果”,不是真实数据,永远不要直接信任。

5.2 工具结果太长,上下文Token爆炸

场景:你的工具函数返回了一大段数据库记录,或者一份几千字的报告文本。每调用一次,这段结果都会作为消息塞进对话上下文。用户提问一句,Agent内部调用3个工具,每个工具返回2000字,上下文瞬间多出6000字。连续多轮对话后,Token消耗指数级上升,费用和响应延迟都跟着涨。

我现在的做法是在工具函数内部做“结果瘦身”。比如,天气接口只返回核心字段,不要全量透传;搜索接口只返回标题和摘要,而不是完整正文。还有一个技巧:如果结果确实很长,可以在工具函数里把内容切成两段——发给模型的是一段摘要,完整数据另外存起来,等模型需要细节时再通过另一个查询工具获取。

5.3 死循环:模型反复调用同一个工具

这是最让人血压升高的一种失控。模型为了获取一个信息,连续调用同一个工具三四次,每次返回的内容都差不多,它却始终不把结果整合成最终答案。我遇到过最离谱的一次,是模型连续调用了五次同一个查询工具,每次的入参都一样,循环就是结束不了。

出现这种情况,通常是工具返回的信息没有触及模型关心的核心点,或者模型压根已经忘了前面调过这个工具。我的解法有三个,叠加使用效果很好:

  • 设置最大迭代轮数,超时就强制终止循环,返回最后一条可用回复
  • 记录同一个连续工具调用的次数,超过两次就打断,在下一轮提示中提醒模型“该工具最近已被调用过,请直接基于返回结果作答”
  • 在系统提示词里明确写:“如果需要的信息已经出现在之前的工具结果中,不要重复调用,直接回答用户”

5.4 工具选择失误:该调的不调,不该调的乱调

模型工具选择失误有两个方向。一种是该调工具时不调,比如用户问“我的账户余额是多少”,模型直接就着历史记忆编了一个数字;另一种是不该调时偏要调,比如用户只是闲聊问“今天天气如何是怎么测出来的”,模型也跑去调天气API。

这两个问题都指向同一件事:模型对“什么情况该用工具”缺乏准确理解。除了在工具description里写清楚边界,我还会在System Prompt里加一段总体的工具使用原则,例如:“当用户的信息需求可能随时间或环境变化时,应使用工具获取实时数据;当问题涉及事实性知识且与实时状态无关时,直接回答。”

6. 日志留痕与评测集搭建:把Agent从“能跑”推向“可信”

6.1 日志是你唯一的线索

Agent系统调试起来比普通接口痛苦得多。普通接口出错,报错信息直接告诉你哪里坏了;Agent出错,往往要回溯好几轮对话,才能看清模型是在哪一步做了错误决策。没有日志,排查这类问题就像在黑暗里找钥匙。

我现在给工具调用流程加的日志,至少要记录这些字段:

记录项说明
request_id一次会话的追踪ID,方便把多轮调用串起来
round_index当前是第几轮工具循环
model_output_tool_calls模型发起的调用请求原文
tool_name / args实际执行了哪个工具、用了什么参数
execution_result_summary工具执行结果摘要,不用记全文,太长
duration_ms每轮调用的耗时
final_answer模型的最终回复原文

这些日志的价值在模型升级时最能体现。有一次我迁移到新版本模型,用户反馈“动不动就乱调工具”,我翻了日志,发现新模型在工具选择上确实比旧版激进得多,几乎每个问题都会强行调一次工具。没有日志的话,我可能还在怀疑是自己的代码出了问题。

6.2 给Agent建一套长期评测集

很多人做Agent时只关注“跑通Demo”,忽略了“长期可维护”。模型版本会迭代,工具定义会修改,提示词会调整,你怎么知道每次改动是变好了还是变差了?这就需要一套固定评测集。

我的做法是准备30个典型任务,覆盖单工具查询、多工具顺序调用、参数格式转换、边界模糊问题这几类场景。每次改动之后跑一遍,统计这几个指标:

  • 工具选择正确率:模型选对工具的比例
  • 参数正确率:每次调用生成参数合法且有意义的比例
  • 任务完成率:评测集里有多少任务被完整解决
  • 平均工具调用轮数:衡量效率,轮数过高说明模型在“绕路”
  • 失败原因分布:是参数幻觉、工具选择失误,还是循环没走出来

这套评测集的价值会随着时间慢慢显现。它不只是验收标准,更是你在做优化时的“尺子”。没有尺子,你所有的调优都只能凭感觉,改完也不知道是真变好了还是心理作用。

最后聊点实在的

做完整个项目,我最深的感触是:Function Calling本身并不难,难的是围绕它搭起的整套Harness。同样的模型,有人接出来的Agent稳如老狗,有人接出来的Agent疯如脱兔,差别往往不在模型,而在工具定义的质量和循环处理的健壮性。

还有一个小技巧,是我后来才加上的,但效果出奇地好:给工具函数设计成幂等的。同一组参数执行一次和执行两次,结果一样,不会重复扣费、重复下单、重复创建会议室。这样就算模型偶尔重复调用某个工具,业务侧也不会出问题。这个经验也是我在踩了几次重复下单的坑之后才总结出来的。希望你不用踩同样的坑。

相关新闻

深度学习分批训练实战:batch_size、DataLoader与显存优化全解析

深度学习分批训练实战:batch_size、DataLoader与显存优化全解析

第一次用 Python 训练一个真正“大数据集”的时候,我以为把几十万条样本一次性加载进内存是天经地义的事。结果程序跑了十几分钟,内存占用一路飙升,最后直接在终端里吐出一串 MemoryError,整个进程当场没了。后来我才意识到&#…

2026/10/21 12:10:01 阅读更多 →
Spring Boot高校学科竞赛平台开发实战

Spring Boot高校学科竞赛平台开发实战

1. 项目拆解:高校学科竞赛平台到底在解决什么问题做这个项目之前,我其实先观察了一个很现实的现象:很多高校的学科竞赛管理还停留在“Excel登记 群公告通知 人工统计”的阶段。学生要找到适合自己的竞赛项目,得反复翻通知群&…

2026/10/20 3:21:02 阅读更多 →
Bambu Studio 3D打印切片软件:从拖入模型到拿到 GCode 的三步

Bambu Studio 3D打印切片软件:从拖入模型到拿到 GCode 的三步

Bambu Studio 3D打印切片软件:从拖入模型到拿到 GCode 的三步 【免费下载链接】BambuStudio PC Software for BambuLab and other 3D printers 项目地址: https://gitcode.com/GitHub_Trending/ba/BambuStudio Bambu Studio 是免费开源的 3D 打印切片软件&am…

2026/10/20 3:21:02 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/21 9:32:40 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/21 9:32:40 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/21 9:32:40 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/21 9:32:40 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/21 9:32:40 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/21 9:31:32 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事:AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里,按宣传口径,本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”,而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起:用户到底在追求什么“封号重开”这四个字,放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流,背后是大量的时间和精力成本。正常情况下,没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”,而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时,就意识到:单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/21 4:27:17 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →