news 2026/10/13 4:46:57

AI Agent架构设计:从单次LLM调用到稳定Harness Runtime

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI Agent架构设计:从单次LLM调用到稳定Harness Runtime

前阵子某个同行问我,AI Agent架构到底怎么选,他们团队已经有一个能用的Demo,但那套代码我扫了一眼,本质上就是一次带上工具的LLM调用加一个while循环,被包装成了Agent。我告诉他,单次调用和完整Harness Runtime之间的差距,不是多写几轮循环的问题,而是流量一上来、任务一乱,你就会发现缺的是对整个执行过程的控制。这篇文章不谈模型效果,只聊从一次LLM调用到稳定Harness Runtime的架构设计与落地经验,适合正在做Agent工程化、或者对现有方案不满意的开发者参考。

1. 核心思路拆解:单次LLM调用与Agent的边界在哪

1.1 一次LLM调用的完整闭环长什么样

先看最朴素形态。假设你要让模型帮你查一个数据库里的订单状态,代码大概是:

  • 构造一个system prompt,告诉模型“你是一个订单助手,可以调用查询工具”
  • 在请求里带上tools参数,里面放一个查询订单状态的function描述
  • 用户问“订单A现在到哪一步了”
  • 模型返回的不是“我帮你查了,是已发货”,而是一个tool_call请求,JSON里指明要调用query_order,参数是{"order_id": "A"}

到这里,你的服务端才真正接手:解析出函数名和参数,调用真实的数据库查询接口,拿结果后作为tool message回填给模型。模型看到查询结果,决定是继续调另外一个工具,还是直接给出最终答案。

这个闭环看似简单,但我见过不少团队把这一套叫做“Agent”。严格来说,这叫工具调用,是Agent的最小能力单元。它解决的问题是:让模型不再只能靠训练数据里的知识回答,而能触达实时数据、内部系统、外部API。这一步的架构决策基本围绕协议和序列化展开,比如tools的JSON Schema怎么写、arguments用字符串还是结构化对象、返回结果怎么截断,都属于这一层。

1.2 从单次调用到多轮循环:Agent的公式

单次调用本质上是“补全”,模型只做一步推断。但真实任务几乎没有一步能完成。比如用户说“帮我对比这三家供应商的报价并给出推荐”,模型需要先逐个查供应商报价,可能还要查历史合作记录,最后才能给出分析。这就必须有一个循环:

初始输入 -> 模型推断 -> 如果是工具调用:执行工具 -> 回填结果 -> 再次交给模型 -> 循环,直到模型输出最终答案。

这个循环看似无脑,真正的复杂度在控制。我见过最典型的翻车现场:某个团队把循环写成while True,结果模型在一个问题上反复调同一个工具,或者说“让我再确认一下”,足足跑了四十多步,最后账单出来远超预算。所以一个合格的Agent循环,至少要有最大步数限制、单步超时、累计预算控制。当这些控制逻辑开始出现,你实际上已经在写运行时的雏形了。我习惯把这层东西叫Harness Runtime,它的职责不是帮你写prompt,而是负责Agent执行过程中所有跟非确定性斗争的事情:解析、路由、重试、终止、成本、观测。

1.3 容易混淆的两层:应用层与运行时层

很多项目烂,不是烂在模型选得不好,而是把运行时逻辑写进了业务代码。你经常能看到业务类里直接写“如果模型返回tool_call就调用这个函数”,函数里又穿插着上下文截断、重试逻辑、日志埋点。表面上都是代码,实际上两层混在一起。

我的划分标准很简单:

  • 应用层管“做什么”,比如查订单、写周报、生成图表,这些逻辑随业务变化,应该由具体Agent实现
  • 运行时层管“怎么稳定地做完”,比如工具怎么注册和发现、上下文怎么管理、调用的结果如何回填、出错怎么重试、调用链路怎么追踪

打个比方,应用层是外卖订单里的菜,运行时层是骑手的电动车、导航路线和调度系统。菜可以天天换,但电动车和调度系统要稳定,否则单量一大必然爆。运行时层一旦跟业务耦合,每接一个新场景都要把循环重写一遍,这不是架构,是堆代码。

2. Agent核心机制拆解:工具注册、记忆管理与执行循环

2.1 工具注册表:不是函数列表那么简单

我看到不少初版实现是把工具直接写成一个Python函数数组,循环里调用func(args)完事。这在Demo阶段没问题,但到生产环境,工具注册表至少要承担四件事。

第一是Schema集中管理。模型需要知道有哪些工具、参数是什么,所以每个工具都必须有name、description、parameters的JSON Schema。description写得清不清晰,直接决定模型选工具的准确率。我见过一个团队把description写得含糊,模型经常选错工具,后来把描述改成带正反例的详细文本,选错率直接降了一半。

第二是权限校验。不是所有工具都允许所有用户调用。订单查询可能只允许管理员,内部数据接口不能暴露给外部Agent。这些拦截应该统一放在注册表层,而不是散落在各个工具实现里。否则你排查“为什么某个用户能查到不该看的数据”时,会痛苦得想重写整个系统。

第三是参数转换。模型返回的arguments是JSON字符串,工具函数不一定接受这种格式,需要做类型校验、默认值补全、非法值清洗。有条件的可以引入Pydantic这类校验库,没条件的也得手写一个集中转换器,否则每个工具开头都有一段重复的“try json.loads”代码,迟早会出错。

第四是返回结果标准化。工具返回的可能是一个对象、一个列表、一段文本,甚至一个异常。注册表最好统一包装成ToolResult结构,包含状态、摘要、耗时、需要回填给模型的内容。我一开始没做标准化,结果有的工具异常抛出来,直接让整个Agent循环崩溃,后来统一成ToolResult并规定异常也要作为正常回填内容传给模型,系统才稳定下来。

2.2 记忆管理:上下文窗口限制下的三层策略

把历史消息一股脑全塞给模型,是最常见也最容易出问题的做法。模型上下文窗口有限,而且窗口内塞得越满,模型对关键信息的注意力越容易被稀释,响应延迟和成本也跟着涨。我习惯把记忆分成三层。

第一层是短期上下文,最近几轮的完整消息。这一层保证模型对话连贯,能知道用户上一句问了什么、当前要解决什么问题。

第二层是中期摘要,当对话超过一定轮数,把更早的内容压缩成一段摘要放进上下文。摘要可以由模型生成,也可以按规则抽取关键字段。这个压缩动作什么时候触发,要根据你的场景摸索。我在一个客服类项目里,定为每四轮做一次摘要,效果不错。

第三层是长期记忆,把用户偏好、历史订单、长期目标这类信息存到外部存储,比如向量库或结构化数据库。这个不能全放进上下文,只在整个任务需要时做一次检索,把相关结果注入。

这三层设计的原因很简单:模型上下文本质上是一个优先级队列,永远应该装最必要的信息。很多人问“模型不是支持200K上下文吗,直接全都给不就行了”,实际上200K的上下文延迟和成本对你的系统压力会非常大,而且信息太多时模型反而抓不住重点。真正生产级的方案永远是截断、摘要、检索三件套。

2.3 执行循环:从盲目重复到可控复用

执行循环是Harness Runtime的心脏。它的基本流程是:接收用户请求 -> 调用模型 -> 检查模型输出 -> 如果是最终答案则结束;如果是工具调用则执行工具 -> 回填结果 -> 继续循环。

但生产环境里,这个循环里隐藏着大量细节。比如你定义了几个状态:idle(空闲)、thinking(模型推理中)、awaiting_tool(等待工具返回)、done(完成)、error(出错)。状态流转清晰以后,你才能判断一个Agent现在到底卡在哪一步,而不是只看日志里一堆模型token记录。

循环里的解析步骤尤其重要。模型输出并不总是规规矩矩的JSON,有时候它会多说一句话、带一段Markdown,甚至把arguments写成非法JSON。解析器必须能提取出真正的tool_call,并在解析失败时做修复和重试。我在实现中至少做了两层解析:先提取JSON块,再用json库解析,解析失败再尝试去掉首尾的不规范字符。

另一个细节是最大步数和终止条件。步数上限可以设为动态值,简单任务10步,复杂分析任务20步,但要防止模型鬼打墙式地反复调用同一工具。我总会在循环里加一个计数map,对同一个工具连续调用超过两次时就给模型提示“该工具结果已获取,请直接基于现有信息回答”,能有效抑制无效循环。

3. 从Agent到Harness Runtime:生产级基础设施问题

3.1 为什么需要Runtime,而不是继续堆框架

很多人问,市面上已经有那么多Agent编排框架,为什么还要自己搞Runtime。我的看法是:框架在快速验证阶段很有价值,它帮你封装好了模型调用、工具调用、内置记忆这些抽象,让你两小时能跑通Demo。但到了生产环境,你会发现框架的抽象是通用的,你的场景是特殊的。

比如框架默认的循环逻辑未必支持你的定制终止条件,框架内置的记忆策略未必适合你的上下文压缩节奏,框架的日志格式未必能对接你已有的监控系统。当这些问题一个个出现时,你面临两个选择:深入框架源码去定制,或者直接自研一个轻量Runtime。两个选择都成立,取决于团队规模和项目复杂度,但无论选哪条,你都必须理解Runtime内部到底发生了什么。这就是为什么我建议所有Agent项目,至少在内部把核心循环自己实现一遍,哪怕只是最小几十行代码,也能让你之后排查问题快得多。

3.2 状态机与任务编排:给Agent建立可中断的执行模型

Agent一旦跑起来,整个生命周期不只是“开始-结束”那么简单。真实场景里有超时、人工审核、依赖等待、并行执行这些分支。状态机是处理这些分支最直观的方式。

我用一个内部模拟项目做过完整的Agent状态机:Agent任务从pending开始,进入running,之后在thinking和tool_execution之间来回切换,最终走到completed或者failed。如果中间需要人工确认,就切到waiting_for_approval,等外部回调恢复。

这个状态机带来的最大收益是可控性。比如某一次任务慢得像蜗牛,运营同学可以直接在后台看到任务停在了waiting_for_approval,而不是只能干等一个神秘黑盒。状态机的实现不复杂,用枚举加一个简单的状态流转判断即可,复杂场景可以引状态图库,但至少内部数据模型要清晰。

3.3 并发调度与工具限流:Agent多了以后必然踩的坑

刚开始做Agent,一个用户一个任务,循环里直接调工具没问题。但Agent服务一旦成为公共能力,多个用户同时发起任务,你的工具接口就变成共享资源了。数据库连接、第三方API配额、内部服务的QPS,每一项都可能被打爆。

我这里踩过一个很实在的坑:某次上线后,Agent频繁调用一个内部查询服务,结果QPS超标,把那个服务直接拖挂了。后来加上两层控制才稳住。第一层是Agent级并发控制,每个任务最多同时执行的工具调用数做限制,比如一个任务最多2个并发工具;第二层是工具级限流,每个工具单独配一个信号量和超时,超过限制的请求直接排队或失败回退。

信号量机制在异步Python里有asyncio.Semaphore可以直接用,简单配置一下就够。对工具返回过慢的情况,统一设置单次工具调用的超时时间,比如15秒,超时就给模型回填“工具超时,请换个方式处理”,这比干等一个不可控的接口要靠谱得多。

3.4 可观测性:把Agent当分布式系统来追踪

Agent循环里每一步都在跟外部系统打交道,只要其中一步出了问题,排查链条就会特别长。所以从第一天做Runtime,就该在关键节点埋点。我常用的采集维度是每次模型调用的token数、耗时、成本,每次工具调用的名称、参数、返回状态、耗时,以及整个任务从开始到结束的状态流转序列。

把这些信息串成一个trace结构,每个任务一个唯一trace_id,每一轮循环一个span,父子关系能直接反映调用链。之前在几个项目里排查问题效率提升非常明显,遇到一个响应异常,直接看trace里卡在哪一步,是模型推理慢还是工具返回慢,一目了然。不需要一开始就上复杂的观测系统,先把trace_id和关键日志打出来,后面要接APM或者自己搭看板都方便。

4. 架构选型对比:常见模式与实战取舍

4.1 三种主流Agent架构模式怎么选

我总结下来,主流的Agent架构模式可以分成三类:ReAct风格、Plan-and-Execute风格、以及分层多智能体风格。

ReAct风格是最基础的,模型在“思考-行动-观察”之间循环,每一步都根据已有信息决定下一步做什么。它的优点是实现简单、灵活性强,适合任务目标不算特别明确、需要边走边看的场景。缺点是每一步都依赖模型的实时判断,步骤一多,累计推理成本和延迟会明显上去。

Plan-and-Execute风格是把任务拆成两段:先让模型做规划,生成一个逐步计划,然后由一个执行器按计划执行,执行过程中再根据实际情况调整。这种模式适合目标明确、步骤清晰的批处理任务,比如“每天定时整理昨天的数据并生成报告”。它的优点是减少反复推理,缺点是计划不准确时,整个任务会走偏,纠错成本高。

分层多智能体风格是有一个主控Agent负责任务拆解和调度,多个子Agent各司其职,比如一个负责查询、一个负责分析、一个负责输出。它适合子任务边界特别清晰、需要不同系统能力组合的场景。但代价是架构复杂度最高,上下文在多Agent之间传递很容易丢失,成本也成倍增长。

选型时我的判断标准是:先看任务是否需要长期规划。如果用户问题通常能在一两次工具调用内解决,就用ReAct;如果用户问题经常是“做一下某某数据报告”这类有明确流程的长任务,用Plan-and-Execute更稳;只有当子任务的专业性差异极大、而且边界非常清晰时,才考虑多智能体。

4.2 单Agent还是多Agent:先别急着组“团队”

多Agent听起来很酷,但至少在我接触过的项目里,大多数场景用单Agent加工具组合就能解决。很多团队一上来就设计三个Agent,一个负责规划、一个负责执行、一个负责总结,结果发现Agent之间的信息同步成了灾难,每个Agent都要重新解释一遍上下文,算下来成本是单Agent的三倍,效果还不一定更好。

我建议先做个简单的判断:任务是否能被拆成有明确输入输出边界的子任务,各子任务之间是否需要频繁共享中间状态。如果答案是“边界不清晰”或“频繁共享”,那就老老实实用单Agent。多Agent真正的价值场景是那种不同领域专家协作的场景,比如财务分析需要同时调用财税知识库、风险规则引擎和报表生成工具,每个子任务都有独立且明确的上下文。

除此之外,我的经验是让一个Agent扮演多角色比拆成多个Agent更省心,只要在system prompt里把不同阶段要用的角色定义清楚,配合工具切换,大多数业务场景足以覆盖。

4.3 框架选型与自研轻量Runtime的平衡

关于用框架还是自研,我见过两种极端:一种是什么都用框架,最后被框架的抽象绑架;另一种是什么都自己写,连基础HTTP调用都要手撸,项目进度慢得没法看。我的建议是分阶段走。

快速验证阶段,直接用主流Agent编排框架,把工具定义好、流程跑通,重点验证业务逻辑和模型效果。这个阶段的核心目标是搞清楚“这个场景到底可不可行”,不值得在底层代码上花太多时间。

进入生产阶段以后,就要开始认真评估框架给你带来了什么、又限制了什么。如果框架的核心循环完全满足你的需求,那就继续用,只是要确保团队里有人能深入源码级排查。如果发现每次定制都很别扭,就要考虑把核心循环收回来自己控制。我自己最后的做法是保留框架的部分工具链,但核心循环和状态机完全自研,这样的组合既保证可控性,又不用重造所有轮子。

5. 实操经验:实现一个轻量Harness Runtime的完整路径

5.1 最小运行时的骨架设计

我先给大家一个可以直接参考的轻量Runtime骨架。我用Python写,异步风格,因为Agent场景天然IO密集,异步能有效提升吞吐。核心类就四个:LLM客户端、工具注册表、记忆管理器、AgentRuntime。

class ToolRegistry: def __init__(self): self._tools = {} def register(self, name, description, parameters, func): self._tools[name] = { "name": name, "description": description, "parameters": parameters, "func": func, } def schemas(self): return [ { "type": "function", "function": { "name": t["name"], "description": t["description"], "parameters": t["parameters"], }, } for t in self._tools.values() ] def execute(self, name, arguments): if name not in self._tools: return {"status": "error", "message": f"tool {name} not found"} try: result = self._tools[name]["func"](**arguments) return {"status": "success", "result": result} except Exception as e: return {"status": "error", "message": str(e)}

这个注册表就是我前面说的统一收口:工具集中管理、执行结果标准化、异常不直接抛出而是转成结构化信息。

5.2 核心循环与终止控制

接下来是AgentRuntime的核心循环。这里展示的是最关键的控制逻辑,包括最大步数、工具调用记录和终止判断。

class AgentRuntime: def __init__(self, llm, registry, memory, max_steps=10, budget=1.0): self.llm = llm self.registry = registry self.memory = memory self.max_steps = max_steps self.budget = budget self.cost = 0.0 async def run(self, user_request): messages = [{"role": "user", "content": user_request}] tool_usage_count = {} for step in range(self.max_steps): response = await self.llm.chat( messages=messages, tools=self.registry.schemas(), ) self.cost += response.cost if self.cost > self.budget: return {"status": "budget_exceeded", "data": messages} if response.tool_calls: for call in response.tool_calls: tool_name = call.function.name arguments = call.function.arguments tool_usage_count[tool_name] = tool_usage_count.get(tool_name, 0) + 1 if tool_usage_count[tool_name] > 2: messages.append({ "role": "tool", "tool_call_id": call.id, "content": "该工具结果已获取,请直接基于现有信息回答,不要重复调用。", }) continue result = self.registry.execute(tool_name, arguments) messages.append({ "role": "tool", "tool_call_id": call.id, "content": str(result), }) continue else: return {"status": "done", "answer": response.content} return {"status": "max_steps_exceeded", "data": messages}

这段代码的核心价值是把终止控制和重复调用抑制直接做进循环里。实际项目中你还会加入trace、超时等,但有了这个骨架,后面所有扩展都有的放矢。

5.3 错误处理与降级策略

模型和工具都是非确定性组件,错误处理不能靠运气。我经过多次踩坑后总结了一套降级策略。

模型输出解析失败时,不要立刻终止整个任务,可以先尝试提取JSON子串、修复引号、再做一次解析。如果还不行,就给模型回填一条“你的输出格式不符合要求,请重新以合法JSON格式返回”,有时一次重试就能解决问题。

工具执行失败时,好的做法不是把异常抛给用户,而是把错误信息以tool message的形式返回给模型,让模型基于错误信息重新决策。要让模型具备自我修正的机会。比如工具报“权限不足”,模型可以直接告知用户没有权限,而不是整个任务崩溃。

连续多次失败时,要果断终止并返回当前已收集到的最有价值信息。我设置过一个规则:同一个工具连续失败三次,就终止该分支,给最终答案加上“部分信息获取失败”的前缀,至少保证用户拿到了能用的部分结果。

6. 常见问题与排查经验实录

6.1 模型一直在循环调用同一个工具

这是最高频的问题,症状是Agent在一个查询动作上反复打转,消耗大量token却没有进展。我排查了几个案例后发现,大部分原因是工具返回的信息不足以支撑模型做下一步决策,或者prompt里缺少明确的终止指导。

解决方案有两步:一是在工具返回结果时尽量包含一个summary字段,直接给模型一个决策依据;二是在system prompt里加入明确指令,比如“当你已经获得足够信息回答用户问题时,必须直接给出最终答案,不得再调用任何工具”。同时,代码层面像我前面展示的,加一个连续调用次数限制,做兜底。

6.2 工具参数JSON解析失败

模型偶尔会把arguments输出成非法JSON,或者混入多余文本。症状很直接,解析器报错,任务中断。遇到这个问题先别骂模型,因为工具参数描述越复杂,模型出错概率越高。

我的排查习惯是把原始输出记录下来,看看是前后多了Markdown代码块标记,还是引号/括号不规范。处理上,解析器要做两层容错:先提取最外层的JSON块,再尝试解析;解析失败时,可以尝试去掉换行、修复单双引号,或者走一次模型自修复。最彻底的办法是模型侧尽量使用结构化输出能力,强制模型按JSON Schema输出。

6.3 上下文被工具返回结果撑爆

工具返回一个几千行的数据表,模型还没开始分析,上下文窗口就快满了。这个问题在查询类工具中特别常见。根治办法是工具侧先做字段裁剪,只返回任务真正需要的字段,比如查询订单就只返回订单号、状态、金额,不要返回所有日志。

再进一步,可以在工具执行后加一个摘要层,当返回内容超过一定字符数时,先用一个轻量模型生成摘要,再把摘要回填给主Agent。我在一个数据分析项目里就这么做,上下文占用直接降到原来的五分之一。

6.4 常见问题速查表

症状可能原因排查方向解决建议
Agent反复调用同一工具工具返回信息不足、缺少终止指令查看工具返回内容是否充分、prompt终止条件是否明确增加summary字段、加连续调用次数限制
参数JSON解析失败模型输出非法JSON、参数描述复杂记录原始输出,检查格式偏离情况多层解析、结构化输出、模型自修复
上下文窗口溢出工具返回内容过多、历史消息堆积统计工具返回字节数、上下文峰值为多少字段裁剪、摘要层、滑动窗口
任务突然中断无结果工具异常抛出、模型输出无法解析查看服务端日志里的异常堆栈和trace统一ToolResult、错误回填模型
成本飙升无预算控制、循环无步数上限查看每次模型调用token数和总步数加预算检查、最大步数、重复调用抑制

6.5 一个排查思路的完整示例

某次线上Agent一直没法回答电商订单问题,用户反馈总是“系统繁忙”。我一开始看应用日志,只看到Agent抛了个KeyError,完全不知道哪一步出问题。后来打开接的Trace,看到一个工具调用的span耗时23秒,紧接着就报错了。

打开工具参数一看,订单号传成了空字符串,而查询工具本身对空参数没做校验,直接抛异常。这个问题的根子其实在参数转换和工具校验两层:一是工具注册表没有对必填参数做前置校验,二是查询工具没有对空字符串做防御。修好这两处,再把错误信息回填机制加上,类似问题就再也没有出现过。这类问题靠模型本身是发现不了的,只有把可观测性做好、把状态流转捋清楚,才能快速定位到具体环节。

最后再分享一点个人经验

在这些Agent项目里摸爬滚打之后,我有两个很深的体会。第一个是,一开始不要想着上多复杂的架构,先把最核心的执行循环写出来,跑通几个真实任务,再一点点加记忆、限流、观测、多Agent。每一步只改一个变量,出了问题能立刻定位。第二个是,Agent运行时的价值往往在系统出问题时才能体现出来。真正让一套Agent架构稳定扛住生产的,不是模型有多聪明,而是围绕循环的控制和兜底做得够不够扎实,所以值得把精力花在基础设施上,别只盯着炫酷的效果。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 4:45:47

MATLAB相场模拟实操:从零搭建选择性激光烧结多颗粒模型

选择性激光烧结(SLS)这几年在金属、陶瓷、聚合物增材制造里火得不行,但真正想从机理上把“激光扫过去,粉末怎么变致密”这件事讲清楚,单靠实验拍片子是远远不够的。颗粒尺度的烧结颈生长、液桥形成、孔隙闭合&#xff…

作者头像 李华
网站建设 2026/10/13 4:45:03

损失函数与梯度推导:从MSE到交叉熵的完整指南

1. 为什么损失函数和梯度推导值得你花时间死磕刚入门深度学习那会儿,我和大多数人一样,上来就model.compile()、model.fit(),跑通了就觉得自己会了。直到有一次自己动手写一个自定义层,反向传播怎么都对不上,梯度要么爆…

作者头像 李华
网站建设 2026/10/13 4:44:19

高速决策AI模型:35倍速度与36项测试准确率第一的架构解析

1. 从"35倍速度"这个数字说起:高速决策AI到底在解决什么问题第一次看到"速度是某类大模型的35倍"这种表述,很多人的第一反应是"又在堆参数、刷榜单"。但如果你真正在业务里部署过决策类AI,就会明白这个数字背后…

作者头像 李华
网站建设 2026/10/13 4:44:17

MySQL CRUD实战指南:从SQL安全、索引优化到事务避坑

1. 这不是语法手册,而是你每天都在写的“数据对话”现场还原在某次线上故障复盘会上,一位后端同事盯着监控曲线突然说:“查了半小时,发现是那条UPDATE语句没加WHERE,把整张用户表的积分全清零了。”会议室里没人笑——…

作者头像 李华
网站建设 2026/10/13 4:43:37

基于Spring Boot+Vue的走失儿童认领登记系统设计与实现

1. 选题思路与项目定位每年都有走失儿童的家庭在各大平台发布寻人启事,而民政、公安、公益组织各自的登记系统相互独立,信息分散在各地各部门,家属往往要跑多个渠道才能完成登记和查询。这种情况下,一个全国范围内的走失儿童认领与…

作者头像 李华
网站建设 2026/10/13 4:43:29

考虑综合负荷的主动配电网最优潮流计算MATLAB实现

配电网潮流计算这个方向,说实话早期做的人都是拿输电网那套方法直接往配网上套。但真把算例跑起来就会发现,结果和现场实测数据对不上。一开始我也以为是数据采集有问题,后来才慢慢意识到,问题出在负荷模型上。配电网和输电网的负…

作者头像 李华