由于写了一个数据清洗+FastAPI的工具demo,链接https://blog.csdn.net/m0_73554446/article/details/160183544?spm=1011.2124.3001.6209

之前写过一个agent的demo,https://blog.csdn.net/m0_73554446/article/details/158645690?spm=1001.2014.3001.5502

所以,在实现数据清洗工具之后,我决定把它接入大模型,套上一层 Agent,就在准备封装的那一刻,突然觉得哪里不对劲。不是报错,而是直觉上的“别扭”。这种别扭,我称之为“微妙的边界”。

第一道边界:控制权的“假象”(你以为你在调度它,其实你在哄它)

在 FastAPI 的世界里,代码是墙:类型注解、Pydantic 校验,错一个字段直接 422 拒绝。

但在 Agent 的世界里,边界是果冻。

大模型是通过自然语言理解你的工具 Schema,然后吐出 JSON 参数来调用的。你以为你是指挥官,实际上你是在“哄小孩”。

比如,我的工具需要一个路径 ./workspace/data.csv
大模型有时候会老老实实传这个,有时候会传 workspace/data.csv(少了 ./),有时候传 /workspace/data.csv(多了个 /)。

如果在传统接口里,我直接 raise HTTPException 了。但在 Agent 里,你不能抛异常,抛了 Agent 就会陷入死循环崩溃。

我发现自己被迫在工具函数里,写下了在传统工程思维里显得有些违和的兜底逻辑

def tool_read_csv(file_path: str) -> str:
    try:
        # 极度宽容的路径处理
        safe_path = os.path.normpath(file_path) 
        if not safe_path.startswith("./workspace"):
            safe_path = os.path.join("./workspace", safe_path.lstrip("./"))
        # ... 读取逻辑 ...
    except Exception as e:
        # 绝对不能抛出 500!必须返回温柔的文字给 AI
        return f"读取失败:{str(e)},能不能帮我检查一下路径?"

那一刻我意识到:把逻辑交给 Agent,就意味着你必须亲手打破自己定下的严格规范,去迁就一个概率模型的随机性。 这道边界,叫“失控”。

第二道边界:它懂“要干嘛”,但不该“干脏活”

我犹豫要不要把清洗逻辑交给 Agent 的第二个原因,是数据本身太脏了。

我的原始数据里充斥着  前端开发#/产品 这种毫无逻辑的乱码。只能靠最硬核的正则去暴力切割:

df["clean_title"] = df["raw_title"].str.replace(" ", "", regex=False)
df["clean_title"] = df["clean_title"].apply(lambda x: re.sub(r"[((].*?[))]", "", x))

大模型在“理解宏观意图”上极具天赋,但在“处理缺乏逻辑的边缘脏数据”时,存在不可控的随机性。如果你让 Agent 自己写代码去处理这堆数据,它会写出极其优雅的、符合 PEP8 规范的代码,但一跑绝对报错。

微妙的边界在于:你不能把脏活交给 AI。 它看似无所不能,实则被死死圈在了它那些干净的训练数据里。如果你想让它干活,你必须把最脏的 Pandas 逻辑封装成黑盒,只允许它当个无情的调包侠。

第三道边界:最让我难受的“维度错位”

这是让我彻底停下键盘,甚至想推翻重来的原因。

我们追求的底层函数长这样(纯内存,极速):

基于字节流,0.5秒出结果
def generate_pdf(file_bytes: bytes) -> bytes:
    df = pd.read_csv(io.BytesIO(file_bytes))
    # ... 清洗、画图 ...
    return pdf_buffer.getvalue()  # 直接吐字节流给前端下载

大模型的工具调用是基于 JSON 协议的,而 JSON 这种数据格式,只支持文本,无法直接承载二进制数据。

如果硬要把这个函数注册给 Agent,在 Schema 里只能这样写:

“请传入 input_path 和 save_path…”

可函数吃的是 bytes !

如果硬逼着对接,就必须写一个极其别扭的“中间人函数”:先接 AI 传来的路径 -> 读文件变成字节流 -> 调我的底层函数 -> 再把输出的字节流存成文件 -> 返回一句文字给 AI。

为了弥合这个维度的错位,不得不引入本可以避免的磁盘 I/O,把原本 0.5 秒的性能拉低,为了让大模型“看得懂”。这种为了迁就模型认知,而在底层工程上做出的妥协,边界感极其微妙。

写在最后:未完成的思考

所以,我停下来了。这个 Agent 接口我现在还没写完。

因为我突然意识到,盲目地把传统代码搬进 Agent,不仅不会变智能,反而会变成一个又慢、又贵、又容易出错的“缝合怪”

我现在脑子里初步有了一个妥协的方案:

  1. 物理隔离: 确定性的“一键下载”按钮,坚决走纯字节流,绝对不碰 Agent。
  2. 降维适配: 如果必须在聊天框里让 AI 用,我就老老实实写一个“降维”的傀儡函数,用牺牲性能的代价,换取认知的对齐。

但这就是最优解吗?我不知道。

大模型工程化落地,最难的根本不是写 Prompt,也不是调 API,而是如何在这个“极度模糊的大脑”和“极度严谨的代码”之间,划定一条清晰的楚河汉界。

这道边界,我还在摸索。等我彻底想通了,把这个模型跑通了,我再回来交卷。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐