Skip to main content

LLM 即函数

SimpleLLMFunc 的核心洞察:LLM 调用应该与 Python 函数调用无法区分。

现有方案的问题

大多数 LLM 框架在你和模型之间引入了新的抽象:
  • 链式框架让你以链接步骤的方式思考,每一步通过框架定义的协议向下一步传递数据
  • 图框架让你定义节点和边,通过可视化 DAG 路由数据
  • Agent 框架将 LLM 隐藏在一个管理自身状态的”代理”抽象背后
所有这些都在你的意图和模型之间放置了一层框架特定的概念。你在学习框架的词汇,而不是直接表达你的任务。

函数模型

在 SimpleLLMFunc 中,LLM 调用就是函数调用:
这是一个完整的、可运行的程序。这个函数:
  • 名称extract_entities
  • 类型化参数text: str
  • 类型化返回值list[Entity]
  • 文档字符串描述行为 — 这就是提示词
  • 可等待的await extract_entities("...")
  • 可组合的 — 从其他函数调用它、传递它、测试它
没有”链”,没有”节点”,没有”Agent 对象”。只有函数。

你获得什么

边界处的类型安全

返回类型注解是一个契约。框架确保 LLM 输出被解析为你声明的类型——否则抛出明确的错误。不需要手动 JSON 解析,不会”有时模型返回字符串而不是对象”。

可组合性

函数天然可组合。用普通 Python 构建复杂管道:
不需要框架 DSL。不需要链定义。只是函数调用函数。

可测试性

像任何其他函数一样 mock 它:

IDE 支持

你的 IDE 已经知道如何处理异步函数、类型注解和文档字符串。自动补全、跳转到定义、内联文档——全部免费。

扩展:LLM 即 Agent

@llm_chat 将函数模型扩展到多轮 Agent。Agent 仍然只是一个函数——它接受输入,返回输出。区别在于它可以使用工具并维护对话状态:
相同的函数接口。相同的可组合性。但现在函数可以在内部跨多个步骤推理(ReAct 循环),使用工具,并流式传输结果。

关键洞察

框架的工作是让”我想调用 LLM”和”我调用了一个 Python 函数”之间的差距尽可能接近零。其他一切——上下文管理、工具执行、类型解析——都是实现细节,你可以忽略它们直到需要自定义。 当你确实需要自定义时,上下文模型给你完全的控制。但默认就是:写一个函数。