news 2026/9/1 23:05:47

DeepSeek Harness实战:从零搭建可扩展的Agent执行框架

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DeepSeek Harness实战:从零搭建可扩展的Agent执行框架

最近不少读者私信问我:网上提到的 DeepSeek Harness 到底是一个框架、一个工具,还是一种开发思路?它和 Agent、工作流、插件开发之间是什么关系?如果我想基于 DeepSeek 搭建一个属于自己的自动化 Agent,应该从哪里下手?

这篇文章就围绕这些问题展开。我会先把 Harness 的概念讲清楚,然后从 DeepSeek API 的基础调用开始,逐步带你设计一个极简但能跑的 Harness 框架,最后实现插件注册、工作流编排和 CLI Agent 落地。无论你是入门不久的新手,还是想把手头脚本升级成 Agent 系统的开发者,都可以跟着实操一遍。

需要提前说明:DeepSeek Harness 相关的开源项目和资料更新速度很快,不同仓库对“Harness”的定义和实现可能不一致。本文重点不是介绍某个特定版本的项目,而是教你基于 DeepSeek API 自己搭建一个轻量级 Harness 执行框架。掌握了这套设计思路,再去阅读其他项目源码,会轻松很多。

1. 什么是 Harness?为什么需要它

1.1 Harness 的直观理解

“Harness” 在英文里原意是“马具、挽具”,它的核心作用是“把动力连接到执行机构上”。在 AI Agent 开发领域,Harness 可以理解为夹在模型能力与应用功能之间的一层“连接装置”。

举个生活中的例子:你有一台高性能发动机(DeepSeek 大模型),但发动机不能直接装到汽车上就跑,必须有变速器、传动轴、控制系统把动力传递到车轮。Harness 就是这套传动和控制系统,它负责:

  • 接收用户请求,统一处理输入格式;
  • 决定调用哪个模型、传哪些参数;
  • 为模型提供工具调用入口;
  • 管理多轮对话状态;
  • 按预定流程编排任务顺序;
  • 收集执行结果并返回给上层应用。

所以“DeepSeek Harness”可以理解为一套专门围绕 DeepSeek 模型设计的执行框架,它让模型不只是“回答问题的聊天机器人”,而是能调用工具、执行任务、参与工作流的 Agent 核心。

1.2 Harness 和 Agent 的区别

很多新手容易把两者混为一谈。这里先做一个区分:

概念定位类比
大模型(DeepSeek)提供智能推理能力发动机
Harness(执行框架)编排模型与工具,控制运行流程整车底盘和控制系统
Agent(智能体)由模型+Harness+工具组成的具体应用整辆汽车
工作流(Workflow)按固定步骤串联任务的执行过程行驶路线

简单来说,Agent 是一个完整应用,Harness 是这个应用的骨架。你可以在 Harness 上接入不同模型、注册不同插件、编排不同工作流,从而构建出不同的 Agent。

1.3 Harness 能解决什么问题

没有 Harness 的 API 调用方式是“一问一答”:

调用模型 -> 得到回答 -> 结束

但真实业务很少这么简单,你需要的是:

接收任务 -> 拆解任务 -> 调用工具获取数据 -> 写入中间结果 -> 再次调用模型分析 -> 输出最终结论 -> 保存执行记录

如果你把这一套逻辑全部写在业务流程代码里,项目很快就会变成一团乱麻:模型调用逻辑、业务逻辑、工具逻辑、状态管理全部耦合在一起。Harness 的价值就是把这些横切关注点统一收口,让业务代码专注于“做什么”,框架负责“怎么执行”。

2. 环境准备与整体架构设计

2.1 环境准备

本文的示例以 Python 3.9+ 为基础,使用openaiSDK 作为 DeepSeek API 的调用客户端。DeepSeek 的接口兼容 OpenAI 协议,所以这样做不需要额外封装底层请求。

# 建议使用虚拟环境 python -m venv venv source venv/bin/activate # Windows 下执行 venv\Scripts\activate # 安装依赖 pip install openai python-dotenv

需要说明的是,SDK 版本不同会导致代码写法略有差异,本文示例以较新的openai>=1.0版本为例。如果你安装的是旧版本,请参考官方文档调整。

安装完成后,在你的项目根目录创建.env文件:

DEEPSEEK_API_KEY=sk-你的Key DEEPSEEK_BASE_URL=https://api.deepseek.com DEEPSEEK_MODEL=deepseek-chat

这里有一个必须注意的安全原则:不要把 API Key 硬编码在 Python 文件中,也不要把.env提交到 Git 仓库。建议在.gitignore中加入:

.env venv/ __pycache__/

2.2 极简 Harness 架构

为了不一开始就陷入复杂的框架设计,我们先搭建一个最小可运行的 Harness。它由四层组成:

层级职责对应模块
接入层处理用户输入,统一调用入口cli.py
编排层管理多轮会话、工具调用、流程控制harness.py
插件层以插件方式扩展工具能力plugins/目录
模型层封装 DeepSeek API 调用llm.py

一个最简单的运行流程如下:

用户输入任务 ↓ Harness 编排层接收任务 ↓ 将任务发送给 DeepSeek 模型 ↓ 模型返回文本或工具调用请求 ↓ Harness 执行工具调用并将结果回传 ↓ 模型生成最终回答 ↓ 返回给用户

这里的“工具调用”是 Agent 能力的核心。DeepSeek 模型支持 function calling,它本身不会直接访问外部系统,但会输出一个结构化的调用请求,由 Harness 去真正执行。

3. 搭建 Minimal Harness:实现 DeepSeek 模型调用

3.1 封装模型调用层

我们先来写模型调用模块。这个模块的职责非常单一:接收消息列表,返回模型的文本回复。

# 文件路径:llm.py import os from dotenv import load_dotenv from openai import OpenAI load_dotenv() client = OpenAI( api_key=os.getenv("DEEPSEEK_API_KEY"), base_url=os.getenv("DEEPSEEK_BASE_URL"), ) DEFAULT_MODEL = os.getenv("DEEPSEEK_MODEL", "deepseek-chat") def chat(messages, model: str = DEFAULT_MODEL, temperature: float = 0.7) -> str: response = client.chat.completions.create( model=model, messages=messages, temperature=temperature, ) return response.choices[0].message.content

这段代码的关键点:

  • load_dotenv()负责加载.env文件中的环境变量;
  • OpenAI()类的base_url指向 DeepSeek 的接口地址;
  • chat()函数把 messages 列表传给模型,并返回文本内容。

3.2 编写 Harness 核心类

接下来是 Harness 的核心类。它需要维护一个会话消息列表,同时提供工具注册和调用的能力。

# 文件路径:harness.py import json from typing import Callable, Dict, List from llm import chat class Harness: """一个极简的 Agent 执行框架。 支持: 1. 多轮会话消息管理; 2. 插件式工具注册; 3. 工具调用自动执行。 """ def __init__(self): self.messages = [] self.tools: Dict[str, Callable] = {} self.tool_schemas: List[dict] = [] def register_tool(self, name: str, func: Callable, description: str, parameters: dict): """注册工具。 Args: name: 工具名称。 func: 对应的 Python 函数。 description: 工具功能描述,供模型理解。 parameters: 参数 JSON Schema 描述。 """ if name in self.tools: raise ValueError(f"工具 {name} 已存在,不允许重复注册") self.tools[name] = func self.tool_schemas.append({ "type": "function", "function": { "name": name, "description": description, "parameters": parameters, } }) def run(self, user_input: str) -> str: """执行一次完整的 Agent 任务。""" self.messages.append({"role": "user", "content": user_input}) # 如果有工具,则把工具描述传给模型;否则直接对话 if self.tool_schemas: response = client.chat.completions.create( model=DEFAULT_MODEL, messages=self.messages, tools=self.tool_schemas, ) else: response = client.chat.completions.create( model=DEFAULT_MODEL, messages=self.messages, ) assistant_message = response.choices[0].message # 如果模型没有请求工具,说明已经得到最终回答 if not assistant_message.tool_calls: self.messages.append(assistant_message) return assistant_message.content or "" # 模型要求调用工具 self.messages.append(assistant_message) for tool_call in assistant_message.tool_calls: function_name = tool_call.function.name function_args = json.loads(tool_call.function.arguments) handler = self.tools.get(function_name) if not handler: raise RuntimeError(f"未注册的工具:{function_name}") # 执行工具调用,并把结果作为 tool 消息返回给模型 tool_result = handler(**function_args) self.messages.append({ "role": "tool", "tool_call_id": tool_call.id, "content": str(tool_result), }) # 工具执行完成后,让模型根据结果生成最终回答 final_response = client.chat.completions.create( model=DEFAULT_MODEL, messages=self.messages, ) final_message = final_response.choices[0].message self.messages.append(final_message) return final_message.content or ""

这段代码虽然简短,但已经具备了 Agent 框架的核心形态:模型负责决策,框架负责执行。值得注意的细节是,工具调用结果要以role="tool"的消息回传给模型,并且必须携带tool_call_id,模型才能把结果关联到对应的调用请求上。

3.3 测试基础对话

先不注册任何插件,跑一个最简单的对话。

# 文件路径:main.py from harness import Harness def main(): h = Harness() answer = h.run("用一句话介绍什么是 Harness") print(answer) if __name__ == "__main__": main()

运行:

python main.py

预期输出类似:

Harness 是一种将大模型能力与工具、工作流连接起来的执行框架,负责编排模型调用和外部操作。

到这里,我们已经完成了 DeepSeek 基础调用 + Harness 类雏形。接下来进入插件开发环节。

4. 插件开发:把工具能力接入 Harness

4.1 什么是 Harness 插件

插件是 Harness 可扩展性的关键。在框架设计里,插件通常指一个独立的功能模块,通过注册机制挂载到主框架上。对于我们的 Harness 来说,一个“插件”就是一个工具函数 + 描述信息 + 参数结构。

插件的好处是解耦。你不需要修改 Harness 核心代码,只需要在 plugins 目录下新增文件,然后注册即可。

4.2 设计一个简单的“时间查询插件”

先实现一个获取当前时间的工具。

# 文件路径:plugins/current_time.py from datetime import datetime def get_current_time(timezone: str = "Asia/Shanghai") -> str: """获取指定时区的当前时间。""" # 实际项目中这里可以用 zoneinfo 处理时区, # 本文为了减少依赖,只返回服务器本地时间。 now = datetime.now() return f"当前服务器本地时间为:{now.strftime('%Y-%m-%d %H:%M:%S')}" # 插件的工具描述信息 TOOL_NAME = "get_current_time" TOOL_DESCRIPTION = "获取当前时间,适合需要知道当前日期时间的任务。" TOOL_PARAMETERS = { "type": "object", "properties": { "timezone": { "type": "string", "description": "时区名称,默认 Asia/Shanghai" } }, "required": [] }

这里单独定义TOOL_NAMETOOL_DESCRIPTIONTOOL_PARAMETERS是为了统一插件的描述规范。随后在main.py中注册插件。

4.3 注册插件并运行

# 文件路径:main.py from harness import Harness from plugins.current_time import ( TOOL_DESCRIPTION, TOOL_NAME, TOOL_PARAMETERS, get_current_time, ) def register_builtin_plugins(h: Harness): """注册内置插件到 Harness 实例。""" h.register_tool( name=TOOL_NAME, func=get_current_time, description=TOOL_DESCRIPTION, parameters=TOOL_PARAMETERS, ) def main(): h = Harness() register_builtin_plugins(h) answer = h.run("现在是几点?请帮我查询一下当前时间。") print(answer) if __name__ == "__main__": main()

运行上面的代码,你会看到模型的处理过程大致是:

  1. 模型发现“当前时间”超出自身知识范围;
  2. 输出tool_calls,申请调用get_current_time
  3. Harness 执行该函数,拿到时间字符串;
  4. Harness 把结果回传给模型;
  5. 模型基于时间内容生成最终回答。

这就是一个带工具调用能力的 Agent 雏形。

4.4 插件开发的注意事项

插件开发过程中,有几个坑需要留意:

  • 参数名要与 JSON Schema 中定义的一致,否则模型生成的参数传不进来;
  • 函数返回值必须是可序列化的,不要返回自定义对象;
  • 插件内部要自己捕获异常,避免工具调用直接导致整个流程崩溃;
  • 敏感操作要加权限校验,避免模型在未经授权时调用危险函数。

5. 工作流实战:编排一个多步骤 Agent

5.1 工作流与 Harness 的关系

如果你理解的“工作流”是自动化流程,那么这个概念和 Harness 并不冲突。工作流更强调“步骤”,Harness 更强调“执行环境”。在实际项目中,你完全可以在 Harness 之上构建工作流:每个工作流步骤本质上就是一个任务节点,节点可以调用模型,也可以调用工具。

下面我们实际编排一个“需求拆解 → 生成验收标准 → 代码审查建议”三步骤工作流,用 DeepSeek 完成每一步文本生成,并在步骤之间传递结果。

5.2 定义工作流节点

我们先用数据类定义步骤节点:

# 文件路径:workflow.py from dataclasses import dataclass from typing import Callable, List @dataclass class WorkflowNode: """工作流中的一个节点。""" name: str task: Callable[[str], str] description: str = "" class Workflow: """一个顺序执行的工作流引擎。""" def __init__(self, nodes: List[WorkflowNode]): self.nodes = nodes def execute(self, initial_input: str) -> str: current = initial_input for node in self.nodes: print(f"--- 执行节点:{node.name} ---") current = node.task(current) return current

在这个设计中,每个节点接收上一个节点的输出,并输出新的文本。这样节点之间天然实现了数据传递。

5.3 基于 DeepSeek 实现三个步骤

接下来创建三个工作流节点。每个节点都使用之前封装好的llm.chat()函数,但传入不同的系统提示词。

# 文件路径:workflow_demo.py from llm import chat from workflow import Workflow, WorkflowNode SYSTEM_PROMPT_REQUIREMENT = ( "你是一名产品经理。请把用户提出的模糊需求拆解为清晰的用户故事," "包括:用户角色、功能描述、业务价值。" ) SYSTEM_PROMPT_ACCEPTANCE = ( "你是一名测试工程师。请基于用户故事,列出完整的验收标准," "覆盖正常流程、异常流程和边界情况。" ) SYSTEM_PROMPT_REVIEW = ( "你是一名资深研发负责人。请基于用户故事和验收标准," "提出开发实现建议和潜在风险。" ) def build_node(system_prompt: str): """生成一个工作流节点:把用户内容交给 DeepSeek 处理,返回模型输出。""" def task(user_content: str) -> str: messages = [ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_content}, ] return chat(messages, temperature=0.3) return task def main(): nodes = [ WorkflowNode(name="需求拆解", task=build_node(SYSTEM_PROMPT_REQUIREMENT)), WorkflowNode(name="生成验收标准", task=build_node(SYSTEM_PROMPT_ACCEPTANCE)), WorkflowNode(name="研发建议", task=build_node(SYSTEM_PROMPT_REVIEW)), ] workflow = Workflow(nodes) initial = "我想做一个团队内部用的工具,让每个人可以提交自己本周完成的工作内容,然后自动汇总成周报。" final_result = workflow.execute(initial) print("\n===== 最终输出 =====\n") print(final_result) if __name__ == "__main__": main()

运行这段代码,你会看到三个节点的中间输出和最终结果。这种串联式工作流的好处是每个步骤职责单一,替换或插入新节点都很方便。

5.4 工作流与 Harness 的融合

上面的工作流并没有使用 Harness,而是直接顺序调用模型。那 Harness 在哪发挥作用?在实际项目中,工作流的节点往往需要访问外部数据。例如:

  • 需求拆解后,需要调用接口获取团队信息;
  • 生成周报前,需要从数据库读取任务列表;
  • 审查代码前,需要调用 Git 获取提交记录。

这些场景就适合把节点内的外部操作封装成插件,注册到 Harness,由 Harness 统一管理工具调用、上下文和多轮会话。你可以把工作流理解为“指挥官”,Harness 理解为“执行机构”,二者配合,才能支撑复杂的 Agent 应用。

6. 搭建专属 Agent:组合 Harness + 插件 + 工作流

6.1 需求场景

现在我们把前面的能力串起来,做一个“周报生成助手”。它的使用流程是:

  1. 用户输入自己本周的工作要点;
  2. Agent 调用“时间工具”获取本周日期范围;
  3. Agent 基于工作要点生成结构化周报;
  4. Agent 调用“保存工具”把结果保存到本地文件。

6.2 新增保存工具插件

# 文件路径:plugins/save_report.py import os from datetime import datetime def save_report(content: str, filename: str = "") -> str: """将文本保存到本地 reports 目录。""" reports_dir = "reports" os.makedirs(reports_dir, exist_ok=True) if not filename: filename = f"weekly_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.md" filepath = os.path.join(reports_dir, filename) with open(filepath, "w", encoding="utf-8") as f: f.write(content) return f"文件已保存到:{filepath}" TOOL_NAME = "save_report" TOOL_DESCRIPTION = "把周报内容保存到本地文件,适合在最终生成结果后调用。" TOOL_PARAMETERS = { "type": "object", "properties": { "content": { "type": "string", "description": "要保存的文件内容" }, "filename": { "type": "string", "description": "可选的文件名,不传则自动生成" } }, "required": ["content"] }

注意,保存文件属于对本地系统执行操作的工具,设计时要考虑:如果将来部署到服务端,必须限制保存路径,防止写入敏感目录。这里为了演示,只用相对路径reports目录。

6.3 实现周报生成 Agent

# 文件路径:weekly_agent.py from harness import Harness from llm import chat from plugins.current_time import ( TOOL_DESCRIPTION as TIME_TOOL_DESCRIPTION, TOOL_NAME as TIME_TOOL_NAME, TOOL_PARAMETERS as TIME_TOOL_PARAMETERS, get_current_time, ) from plugins.save_report import ( TOOL_DESCRIPTION as SAVE_TOOL_DESCRIPTION, TOOL_NAME as SAVE_TOOL_NAME, TOOL_PARAMETERS as SAVE_TOOL_PARAMETERS, save_report, ) def create_weekly_agent() -> Harness: h = Harness() h.register_tool( name=TIME_TOOL_NAME, func=get_current_time, description=TIME_TOOL_DESCRIPTION, parameters=TIME_TOOL_PARAMETERS, ) h.register_tool( name=SAVE_TOOL_NAME, func=save_report, description=SAVE_TOOL_DESCRIPTION, parameters=SAVE_TOOL_PARAMETERS, ) return h def main(): agent = create_weekly_agent() # 给 Agent 注入系统提示词,明确它的角色和输出格式 agent.messages.append({ "role": "system", "content": ( "你是一名周报助手。用户会提供本周的工作要点。" "请先查询当前时间,确认周报日期范围。" "然后生成 Markdown 格式的周报,内容包括:" "本周工作回顾、下周计划、问题与风险。" "最后调用 save_report 工具把周报保存到本地。" ) }) user_input = ( "本周完成了 DeepSeek 接口联调,封装了模型调用模块;" "设计了 Harness 框架的插件注册机制;" "下周计划完善工作流引擎,增加错误重试能力。" ) result = agent.run(user_input) print("===== Agent 最终回答 =====") print(result) if __name__ == "__main__": main()

运行这个文件,你可能看到的执行过程是:

  1. Harness 把系统提示词和用户任务一起发给 DeepSeek;
  2. DeepSeek 判断需要先知道当前时间,于是请求调用get_current_time
  3. Harness 执行时间插件,返回时间给模型;
  4. 模型根据时间生成周报文本;
  5. 模型继续请求调用save_report
  6. Harness 执行保存操作;
  7. 模型返回最终确认信息。

至此,你已经拥了一个可以扩展的专属 Agent:框架代码在harness.py,插件在plugins/目录,业务配置在main脚本里。后续想增加能力,不需要改框架代码,只需要新增插件并注册。

7. 常见问题与排查思路

DeepSeek Harness 开发过程中,会遇到很多实际问题。这里整理几个高频场景,按“现象 → 原因 → 解决思路”的格式列出。

问题现象常见原因解决思路
调用 API 报401 UnauthorizedAPI Key 错误或未正确加载检查.env文件,确认DEEPSEEK_API_KEY正确;确认没有在代码中覆盖api_key参数
调用 API 报超时错误网络环境不稳定或请求内容过长OpenAI客户端中设置timeout参数;拆分为多个步骤处理长文本
模型返回的内容为空上下文为空或参数max_tokens过小检查 messages 是否为空;在请求中显式设置足够的max_tokens
工具调用报“未注册的工具”插件注册失败或名称拼写不一致打印h.tools.keys()检查注册列表;确认TOOL_NAME严格一致
工具执行结果无法回传给模型缺少tool_call_idrole不正确确认回传消息中包含tool_call_id,且role="tool"
多轮对话后上下文越来越长没有做历史消息截断对长时间运行的 Agent 设置消息窗口,只保留最近 N 轮
插件函数参数不匹配JSON Schema 定义与函数签名不一致统一使用**function_args方式传参,并在注册时校验参数名
服务器部署后无法读取.env环境变量未加载或路径不对使用绝对路径加载.env,或改用系统环境变量

如果你遇到模型不停请求同一个工具,然后报错退出,优先怀疑工具函数内部抛了异常。建议在工具函数入口输出调试日志,确认参数是否合法。

另外,“The agent execution provider did not respond in time”这类报错,通常表示本次请求超时。它可能由网络波动、模型负载高或请求体过大引起。解决思路是:重试一次、缩短上下文、把复杂任务拆成多个子任务。

8. 最佳实践与工程建议

当 Harness 从 Demo 走向真实项目时,下面这些工程经验会帮你少踩很多坑。

8.1 全局异常处理与重试

模型调用是不可靠的,网络抖动、接口限流、服务端异常都可能发生。建议对chat()函数做统一的异常封装和重试。

import time from openai import APIConnectionError, APIStatusError from llm import DEFAULT_MODEL, client def chat_with_retry(messages, model=DEFAULT_MODEL, retries=3, **kwargs): for attempt in range(retries): try: response = client.chat.completions.create( model=model, messages=messages, **kwargs, ) return response.choices[0].message.content except (APIConnectionError, APIStatusError) as e: if attempt == retries - 1: raise time.sleep(2 * (attempt + 1))

8.2 密钥与权限管理

在任何环境里都不要把 API Key 提交到代码仓库。团队协作时建议使用密钥管理平台。对于可能破坏数据的插件,比如删除文件、修改数据库,一定要增加二次确认机制,或在 Harness 层做白名单拦截。

8.3 上下文长度控制

DeepSeek 模型有上下文窗口限制。多轮对话中,历史消息会不断累积,导致 Token 消耗增加、响应变慢。建议在 Harness 中增加一个简单的截断策略:

def trim_messages(self, max_turns=10): """只保留最近 max_turns 轮用户和助手消息。""" if len(self.messages) > max_turns * 2: self.messages = self.messages[:1] + self.messages[-(max_turns * 2):]

这里保留第 1 条含义取决于你的消息列表第一条是不是系统提示词。如果是,则保留它;如果不是,可以调整起始索引。

8.4 日志与可观测性

Agent 的决策链路比较长,出了问题很难排查。建议记录以下信息:

  • 每次请求的模型、参数、Token 消耗;
  • 模型的工具调用请求内容;
  • 工具函数的入参和返回结果;
  • 工作流每个节点的耗时和输出摘要。

先用最简单的logging模块,等业务规模变大后再接入链路追踪系统。

8.5 测试策略

Harness 的核心逻辑是“模型决策 + 工具执行”,所以测试要分层:

  • 单元测试:只测插件函数,传入固定参数,断言返回值;
  • 集成测试:用一个 Mock 模型响应来验证 Harness 是否能正确解析工具调用;
  • 回归测试:跑一组固定的用户输入,对比输出质量,防止升级模型后效果变差。

8.6 版本管理与兼容性

DeepSeek API 的返回结构、SDK 的行为、模型的 function calling 表现都可能变化。建议:

  • requirements.txt中锁定 SDK 版本;
  • 对模型名称使用配置项,不要硬编码;
  • 定期检查官方变更日志。

9. 总结与下一步学习路线

到这里,你已经完整走了一遍 DeepSeek Harness 的开发闭环:理解了 Harness 和 Agent 的关系,封装了 DeepSeek API 调用层,实现了带插件注册机制的 Harness 核心类,开发了时间查询、文件保存两个插件,并组合出一个周报生成 Agent,最后了解了常见的异常排查方法和工程落地建议。

按照这个进度,下一步可以按顺序深入学习这几个方向:

  • 熟悉 DeepSeek API 的官方接口文档,重点看 function calling 的参数是支持情况和具体限制;
  • 扩展 Harness 的插件系统,支持动态加载、配置化注册,而不是每次改代码;
  • 引入消息队列,把工作流改造成异步执行的流水线;
  • 研究开源 Agent 框架中 Harness 模块的实现,对比本文的最小实现,理解工业级框架做了哪些抽象。

最后给你一个实用的建议:不要一开始就追求复杂的 Agent 框架。先用本文这套最小结构跑通一个真实业务场景,哪怕只是“生成日报并保存到本地”这样的简单任务。跑通以后,你会对模型调用、工具注册、消息回传、工作流编排有更直观的感觉,再去看那些功能更强大的框架,就能看懂它们的设计取舍了。

如果这篇文章对你有帮助,可以收藏备用,后续再遇到 DeepSeek 相关开发问题,随时回来翻一翻。

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

美团技术岗笔试全解析:考点拆解、编程题复盘与避坑指南

1. 笔试前你需要知道的那些事 2025年的秋招,比往年更早敲响了战鼓。美团作为互联网大厂里的热门选手,技术岗的第一批笔试往往在8月中下旬就拉开帷幕。很多同学还在暑期实习的尾巴上挣扎,突然发现笔试通知已经躺在了邮箱里——那种"还没准…

作者头像 李华
网站建设 2026/9/1 23:03:09

RAP Singleton Pattern 深度解析,一条技术根实例如何撑起整页编辑与表单录入

做过 SAP S/4HANA 业务配置类应用,很容易遇到一种和传统 CRUD 完全不同的页面需求。业务人员打开应用之后,并不希望先面对一个 List Report,再选择某条记录进入 Object Page。他们真正想看到的往往是一整张可以直接维护的配置表,或者是一张已经进入编辑状态的业务表单。 这…

作者头像 李华
网站建设 2026/9/1 23:03:05

S/4HANA 里 MARC 库存字段为何在自定义 CDS View 中变成 0,TRAME、NSDM 与 CDC 的完整排查逻辑

S/4HANA 里 MARC 库存字段为何在自定义 CDS View 中变成 0,TRAME、NSDM 与 CDC 的完整排查逻辑 最近在做一条从 SAP S/4HANA 抽取数据到 SAP Datasphere 的链路时,我碰到了一个非常具有迷惑性的问题。 数据源是大家非常熟悉的 MARC,也就是物料的工厂级数据。因为下游不仅需…

作者头像 李华
网站建设 2026/9/1 23:01:30

STM32H743硬件JPEG解码显示实战:从SD卡到LTDC全链路源码解析

简介:本资源是一套基于STM32H743单片机实现硬件JPEG解码与LCD显示的完整嵌入式开发源码,面向具备C语言基础和STM32外设开发经验的中级以上嵌入式工程师及高校电子类专业学生,解决高性能图像实时解码在资源受限MCU上的落地难题。压缩包共844个…

作者头像 李华
网站建设 2026/9/1 23:00:27

5欧电阻并联 22uF 及 0.1uF电容组成的 R/C滤波网络,滤波效果分析

AVCC 电源经过串联的 5欧姆电阻和后续并联的 22uF 及 0.1uF电容组成的 R/C滤波网络, 滤波效果如何,如 10KHz / 100KHz / 1MHz / 10MHz / 20MHz / 30MHz / 40MHz / 50MHz / 100MHz / 200MHz 的电源干扰,效果如何 ? 从 AVCC消耗电…

作者头像 李华
网站建设 2026/9/1 22:59:00

ArcGIS地图数据处理全流程:从加载、裁剪到坐标对齐与报错排查

简介:一份ArcGIS地图数据压缩包,内含城市级、洲级、世界级三类图层,并附带mxd地图文档与shp矢量数据,适合GIS开发、地图制图及二次开发人员参考使用。资源共24个文件,压缩后约899KB,主要文件类型包括mxd地图…

作者头像 李华