十一国庆正是充电的好时机,借着假期时间充裕,笔者又浅调研了一下本地LLM开发相关的工具链,看下如果是日常业余搞个人LLM的Agent项目,具体有哪些能力可用。工业界的话,因为知识保密性等各种原因,我们可能会用到兄弟部门的LLM模型或者相关Agent能力,以及市面上收费但企业内部免费的一些技术基建。但如果是个人搞LLM应用开发,就更加倾向于看有没有低成本甚至免费的办法去做本地研发了。
基于这个目的,经过一番调研实操,发现只需要一个Agent开发框架加上模型Provider就能解决问题。因此本文就介绍一下,以Agent开发框架Eino,加上Ollama这个模型Provider,如何能够低成本研发LLM的Agent。针对这个主题,虽然以前也写过用Coze开源版研发的Case,但Coze本身作为一套工业界产品基建,直接拿它工作还是比较重的,本文暂且只讨论一些比较轻量的事情。
首先咱们需要理解模型对标现实中的啥,具体怎么提升生产力。按笔者粗浅理解的话,一个模型实例就相当于一个大脑,它节省开发者工作量的地方在于,以前的程序是开发者一行行代码编写出来的,而现在我们可以通过微调或者工具增强等方式定制化一个大脑,使得在尽可能减少确定性折损的条件下,低成本做多模态的数据转换,甚至实现另一套我们需要的程序。不管这个理解是不是精确,但至少有了这个想法的话,开发一个LLM应用思路会清晰的多。
在本地,我们可以借助Ollama工具管理多个大脑,每个大脑有不同的能力,比如gemma3可以处理视觉信息,qwen3可以做外部工具识别,bge-m3可以做文本向量化(embedding),deepseek-r1具备自思考能力,然后基本上每个模型都有问答能力,等等。在具体实现上,我们可以组合不同的模型,打造一套完善的Agent。
比方说有用户问,想要去某个图片里面的地方旅游,有什么方案?那么我们的Agent可以实现成,首先借助deepseek-r1的思考能力做意图识别,发现问题包含额外图片信息,之后就调用gemma3模型(或是封装的Agent)做图片识别,识别图片里的关键地标信息,再之后结合向量数据库跟我们通过bge-m3模型embed的大量文本,我们可以构建一套地理知识库,在这个知识库里检索到这个地标对应的城市,最后再借助qwen3以及外部高德地图等工具,规划出一套完整的旅行方案,回给主脑deepseek-r1吐出来。具体怎么管理Ollama的模型,可以参考Ollama官方文档。
为了实现这样的编排,我们需要有一套Agent开发框架,常见的就是基于Python的LangChain以及基于Golang的Eino。本文以Eino为例子,Eino内部有封装对Ollama的调用,所以通过Eino连接Ollama模型也比较简单,示例代码:
1 | func (a *EinoOllamaAgent) Run(ctx context.Context) { |
如果是需要构建知识库的场景,那么我们需要做的一是把embedding模型当成通用文本向量化工具,不单独写一套代码,二是引入一个向量数据库,持久化文本向量,提供知识访问能力。如果用Eino实现的话,先给一个以内存作为向量数据库的最简单例子,当然Eino本身也有很多向量数据库Client的抽象,此处不赘述了。
1 | type Doc struct { |
值得一提的是,如果这段代码转成Python也是比较容易的,比如Trae这种善于处理代码任务的Agent就可以做不同语言代码转换。假使用LangChain实现,外加ChromaDB本地持久化向量文本的话,可以这样写:
1 | from langchain_community.embeddings import OllamaEmbeddings |
对于复杂编排,除了可以考虑用Dify之类的可视化工具做之外,纯程序的话,Eino也提供了一套ADK框架封装了更复杂的Agent编排功能。除了最基础的ChatModelAgent之外,再往上实现的是WorkflowAgents,里面包括Sequential、Loop以及Parallel等编排,也就是行为树的翻版,然后再继续往上就实现了Supervisor以及Plan-Execute两类封装好的应用级编排。
对于调研类任务的话,有一个封装好的Plan-Execute编排,加上靠谱的数据处理模型,就可以实现一个简单的调研类Agent:
1 | type EinoAdkAgent struct { |
最后,如果说要把Agent效果继续优化的话,先是要有一套完善的评测系统,然后也需要有一个Trace工具了解整个Agent链路上的弱点,最后可以从工具、Prompt、模型FineTune等很多角度去做优化,从而不断完善Agent的能力。要实现一个Demo很容易,但打磨产品的任务仍然任重道远。