首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >WorkBuddy 工程化实战:从 Agent Loop 到 Harness 的分层解耦

WorkBuddy 工程化实战:从 Agent Loop 到 Harness 的分层解耦

原创
作者头像
IT大佬 jzit-top
发布于 2026-10-13 15:35:31
发布于 2026-10-13 15:35:31
710
举报

核心结论: WorkBuddy 的工程价值不在于“又一个 Agent 产品”,而在于它用五层架构和 Harness 工程把 Agent 从“能跑”推向了“可控”——Agent Loop 只是其中最基础的一层,真正让它在生产环境中稳定运行的,是 Loop 外面的上下文隔离、权限控制和结果验证机制。

一、为什么 Agent Loop 单独不够用

一个常见的认知误区是:把 Agent Loop 等同于 Agent。ReAct 是 Loop,Plan-and-Execute 是 Loop,只要把“思考-行动-观察”摆出来,Agent 就搭好了。

但 WorkBuddy 团队在工程复盘中明确指出:模型只承担其中一部分——工具接入、上下文组织、权限边界、结果验证、反馈纠正和跨会话延续,都会直接影响产品是否可靠。模型本身是无状态的,对话历史、Memory、工作进度都需要产品侧维护状态再注入。

用一个简化的 Loop 代码来说明这个缺口:

代码语言:javascript
复制
# 最简 Agent Loop —— 能跑,但不可控
def naive_agent_loop(task, tools, max_steps=20):
    messages = [{"role": "user", "content": task}]
    for _ in range(max_steps):
        resp = llm.chat(messages, tools=tools)
        if resp.tool_calls:
            for tc in resp.tool_calls:
                result = execute_tool(tc)  # 无权限检查
                messages.append({"role": "tool", "content": result})
        else:
            return resp.content
    return "达到最大步数,任务未完成"  # 无中间状态保存

这段代码有三个致命问题:工具调用没有权限边界,Agent 可以执行任何命令;每一步的上下文全量传给模型,token 消耗随步数线性增长;循环没有状态持久化,中断后无法恢复。WorkBuddy 的 Harness 工程正是为解决这些问题而设计的。

二、WorkBuddy 五层架构与 Harness 工程

WorkBuddy 的整个系统从下到上分为五层:基础设施层、智能体底座层、能力服务层、业务应用层和用户交互层,每一层只和相邻层通信。其中与开发者关系最密切的是智能体底座层的能力服务层。

智能体底座层继承自 CodeBuddy 的智能体内核,包含自然语言理解器、任务规划器、工具调用器和执行监控器四个核心组件。这一层在 Agent Loop 的基础上,叠加了 Harness 工程机制:上下文隔离(每个工具调用只看到自己需要的上下文)、权限边界(沙箱模式控制文件系统访问范围)和结果验证(每一步执行后检查产出是否符合预期)。

以下是模拟 WorkBuddy Harness 层核心逻辑的代码,展示了 Loop 如何被外围机制约束:

代码语言:javascript
复制
from dataclasses import dataclass, field
from enum import Enum

class PermissionMode(Enum):
    READ_ONLY = "read_only"       # 只读,禁止写入
    WORKSPACE_WRITE = "workspace" # 仅工作空间可写
    FULL_ACCESS = "full"          # 无限制

@dataclass
class HarnessLoop:
    """带 Harness 约束的 Agent Loop"""
    tools: dict
    permission: PermissionMode = PermissionMode.WORKSPACE_WRITE
    max_steps: int = 20
    state: dict = field(default_factory=dict)

    def _check_permission(self, tool_name: str, args: dict) -> bool:
        """权限边界检查"""
        if self.permission == PermissionMode.READ_ONLY:
            return tool_name in ("read_file", "search", "glob")
        if self.permission == PermissionMode.WORKSPACE_WRITE:
            path = args.get("path", "")
            return not path.startswith("/etc") and not path.startswith("C:\\Windows")
        return True

    def _trim_context(self, messages: list, max_tokens: int = 8000) -> list:
        """上下文裁剪:只保留最近 N 轮 + 系统提示词"""
        system = [m for m in messages if m["role"] == "system"]
        recent = [m for m in messages if m["role"] != "system"][-6:]
        return system + recent

    def run(self, task: str) -> str:
        messages = [{"role": "system", "content": "你是 WorkBuddy"},
                    {"role": "user", "content": task}]
        for step in range(self.max_steps):
            trimmed = self._trim_context(messages)
            resp = llm.chat(trimmed, tools=list(self.tools.keys()))
            if not resp.tool_calls:
                return resp.content
            for tc in resp.tool_calls:
                if not self._check_permission(tc.name, tc.args):
                    messages.append({"role": "tool",
                                     "content": "权限拒绝:当前模式不允许此操作"})
                    continue
                result = self.tools[tc.name](**tc.args)
                self.state[f"step_{step}_{tc.name}"] = result  # 状态持久化
                messages.append({"role": "tool", "content": str(result)})
        return "任务未在限定步数内完成"

这个实现比最简 Loop 多了三件事:权限检查拦截越界操作,上下文裁剪控制 token 消耗,状态持久化支持中断恢复。这就是 Harness Engineering 在 Loop 层面的具体落地。

三、实战:用 MCP 把外部 API 接入 WorkBuddy

WorkBuddy 的能力服务层支持 MCP(Model Context Protocol)协议,这是让 Agent “长出手脚”的关键机制。以下是一个将内部订单查询 API 暴露为 MCP Tool 的完整示例:

代码语言:javascript
复制
from mcp.server import Server
from mcp.types import Tool, TextContent
import httpx

server = Server("order-query")
ORDER_API = "http://internal.example.com/api/orders"

@server.list_tools()
async def list_tools():
    return [Tool(
        name="query_order",
        description="根据订单号查询订单状态、金额和物流信息",
        inputSchema={
            "type": "object",
            "properties": {
                "order_id": {"type": "string", "description": "订单号"}
            },
            "required": ["order_id"]
        }
    )]

@server.call_tool()
async def call_tool(name: str, arguments: dict):
    if name == "query_order":
        async with httpx.AsyncClient() as c:
            resp = await c.get(f"{ORDER_API}/{arguments['order_id']}",
                               timeout=10)
            data = resp.json()
        return [TextContent(
            type="text",
            text=f"状态:{data['status']},金额:{data['amount']}元,"
                 f"当前位置:{data['location']}")]

if __name__ == "__main__":
    import mcp.server.stdio
    mcp.server.stdio.run(server)

写完这个 Server 后,在 WorkBuddy 的 ~/.workbuddy/mcp.json 中注册即可让 Agent 直接调用:

代码语言:javascript
复制
{
  "mcpServers": {
    "order-query": {
      "command": "python",
      "args": ["/path/to/order_server.py"],
      "env": {}
    }
  }
}

MCP 的核心价值在于:你写一次 Server,所有支持 MCP 的客户端通用——WorkBuddy、Claude Desktop、Cursor 都能即插即用,不需要为每个客户端重写集成代码。

四、工程化落地要点

第一,节点粒度按工作性质分,不按步骤分。 信息收集类的工作放一个 Loop 里,不要拆成“读文件”和“读数据库”两个独立循环。推理类的工作单独隔离。

第二,回边必须设次数上限。 任何可能反复执行的路径(如“验证失败则重新生成”),都要设定 max_iterations,跑完还没收敛就跳出并报告“未收敛”。

第三,节点间状态传递要结构化。 不要用自然语言在 Loop 之间传递中间结果,用明确的 schema 定义输入输出。WorkBuddy 的实践表明,每个环节的输出应该是能被下一环节直接使用的结构化输入,链路才是可反馈的环,而不是断开的直线。

第四,权限边界是最后一道闸。 日常用 Workspace Write(仅工作空间可写),只查不改时切 Read Only,Full access 用完立刻切回。这是 WorkBuddy 安全性设计的核心原则。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、为什么 Agent Loop 单独不够用
  • 二、WorkBuddy 五层架构与 Harness 工程
  • 三、实战:用 MCP 把外部 API 接入 WorkBuddy
  • 四、工程化落地要点
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档