LlamaAI本地部署实战专栏第8篇

前面我们已经完成了本地LLM、CUDA加速、API服务以及Hybrid RAG。

现在进入一个更重要的阶段:

让大模型从“会回答问题”升级到“能够执行任务”。


一、从Chatbot到Agent

到目前为止,我们的系统已经可以:


用户
 ↓
本地Llama
 ↓
RAG检索
 ↓
知识库
 ↓
生成答案

例如:

RTX 4060运行7B模型需要多少显存?

Llama可以根据知识库回答。

但是如果用户说:

帮我查看一下当前项目目录有哪些文件。

普通LLM只能告诉你:

我无法直接访问你的电脑。

为什么?

因为:

LLM本身只是一个模型,它不会自动获得操作系统权限。


二、Agent到底是什么?

AI Agent可以简单理解为:

LLM + Tools + Decision Loop

也就是:


大语言模型
+
工具
+
执行循环

传统Chatbot:


用户
 ↓
LLM
 ↓
答案

Agent:


用户
 ↓
LLM
 ↓
判断任务
 ↓
选择工具
 ↓
执行工具
 ↓
获得结果
 ↓
再次交给LLM
 ↓
继续执行
 ↓
最终答案

因此:

Chatbot负责“回答”。

而:

Agent负责“完成任务”。


三、一个最简单的Agent例子

用户:

帮我计算 123 × 456。

普通LLM:


123 × 456 = 56088

Agent:


用户
 ↓
LLM
 ↓
发现需要计算
 ↓
调用Calculator工具
 ↓
得到56088
 ↓
LLM
 ↓
返回答案

区别就在于:


LLM
 ↓
Tool

四、Agent的核心组成

一个完整Agent通常包含:


┌────────────────────┐
│       User         │
└─────────┬──────────┘
          ↓
┌────────────────────┐
│        LLM         │
└─────────┬──────────┘
          ↓
   Tool Selection
          ↓
┌────────────────────┐
│       Tools        │
│                    │
│ 文件读取           │
│ 搜索               │
│ Python             │
│ 数据库             │
│ API                │
└─────────┬──────────┘
          ↓
       Tool Result
          ↓
         LLM
          ↓
       Final Answer

其中最重要的是:

Tool Calling。


五、什么是Tool Calling?

Tool Calling可以理解成:

LLM告诉程序:“我需要调用哪个工具,以及参数是什么。”

例如我们定义:


def calculator(a, b):
    return a + b

告诉LLM:


工具名称:

calculator

参数:

a
b

用户:

计算12+30。

LLM可能返回:


{
  "tool": "calculator",
  "arguments": {
    "a": 12,
    "b": 30
  }
}

程序看到以后:


calculator(12, 30)

得到:


42

然后把:


42

重新交给LLM。

最终:

答案是42。


六、Agent并不是“模型自己执行程序”

这里一定要理解一个概念。

LLM不能直接:


删除文件
执行Shell
读取数据库

真正执行操作的是:


你的程序

所以实际关系:


       LLM
        │
        │ Tool Call
        ↓
   Agent Runtime
        │
        ↓
      Tool
        │
        ↓
    操作系统

LLM只是:

决策者。

Python/C++程序才是:

执行者。


七、先实现一个Calculator Agent

为了理解Agent,我们先不用复杂框架。

直接Python实现。

定义工具:


def calculator(a, b, operation):

    if operation == "add":
        return a + b

    if operation == "sub":
        return a - b

    if operation == "mul":
        return a * b

    if operation == "div":
        return a / b

    return "unknown operation"

工具描述:


calculator_tool = {
    "name": "calculator",
    "description": "执行基础数学计算",
    "parameters": {
        "a": "number",
        "b": "number",
        "operation": "string"
    }
}

八、Agent工作循环

核心逻辑其实非常简单:


while True:

    response = llm(messages)

    if response需要调用工具:

        tool_result = execute_tool(
            response
        )

        messages.append(
            tool_result
        )

    else:

        return response

这就是Agent最核心的:

循环(Loop)。


九、Agent为什么需要循环?

假设用户:

帮我读取项目README,然后总结项目用了哪些技术。

Agent可能执行:


第1轮:

LLM
 ↓
调用read_file
 ↓
README.md

得到:


README内容

然后:


第2轮:

README
 ↓
LLM
 ↓
分析内容

最终:


项目使用:

Python
FastAPI
FAISS
llama.cpp

如果没有循环:


LLM
 ↓
只能执行一次

复杂任务就无法完成。


十、让Agent读取本地文件

我们定义:


def read_file(path):

    with open(
        path,
        "r",
        encoding="utf-8"
    ) as f:

        return f.read()

现在Agent拥有:


read_file()

工具。

用户:

读取README.md并告诉我项目使用什么技术。

Agent:


用户
 ↓
LLM
 ↓
read_file("README.md")
 ↓
获得文件内容
 ↓
LLM分析
 ↓
答案

十一、再增加一个目录工具

定义:


import os


def list_files(path):

    return os.listdir(path)

现在Agent拥有:


Tools:

list_files
read_file
calculator

用户:

找一下项目里有哪些Python文件。

Agent:


list_files()
 ↓
获得文件列表
 ↓
找到.py文件
 ↓
回答

十二、Agent + RAG

现在开始把前面两篇连接起来。

之前:


用户
 ↓
RAG
 ↓
知识库
 ↓
Llama

现在:


用户
 ↓
Agent
 ↓
判断是否需要知识
 ↓
RAG Tool
 ↓
FAISS + BM25
 ↓
返回资料
 ↓
Llama

于是:

RAG不再只是固定流程,而可以成为Agent的一个工具。

例如:

用户:

根据公司的技术文档,告诉我GPU部署要求。

Agent:


LLM
 ↓
需要查知识库
 ↓
调用search_knowledge
 ↓
BM25 + FAISS
 ↓
Reranker
 ↓
返回相关文档
 ↓
LLM
 ↓
答案

十三、最终Agent架构

现在系统开始变得有意思了:


                       用户
                        ↓
                      Agent
                        ↓
                       LLM
                        ↓
              ┌─────────┼─────────┐
              ↓         ↓         ↓
             RAG      文件      Calculator
              ↓         ↓         ↓
           FAISS     File IO    Python
              ↓         ↓         ↓
              └─────────┼─────────┘
                        ↓
                       LLM
                        ↓
                      答案

这就是:

Tool-augmented LLM。


十四、如何让本地Llama调用工具?

前面我们已经在第5篇中启动了:


llama-server

现在:


Python Agent
      ↓
OpenAI-compatible API
      ↓
llama-server
      ↓
本地Llama

Python:


from openai import OpenAI


client = OpenAI(
    base_url="http://localhost:8080/v1",
    api_key="none"
)

然后给模型传递工具定义。

概念上:


tools = [
    {
        "type": "function",
        "function": {
            "name": "calculator",
            "description": "执行数学计算",
            "parameters": {
                "type": "object",
                "properties": {
                    "a": {
                        "type": "number"
                    },
                    "b": {
                        "type": "number"
                    }
                }
            }
        }
    }
]

然后:


response = client.chat.completions.create(
    model="local-model",
    messages=messages,
    tools=tools
)

模型如果决定调用工具,就会返回对应的Tool Call。


十五、Agent Runtime到底做什么?

这是工程实现中非常重要的一层。

不要把所有东西:


LLM
+
Tool
+
业务逻辑

全部写在一起。

推荐架构:


agent/
│
├── agent.py
│
├── runtime.py
│
└── tools/
    │
    ├── calculator.py
    ├── file.py
    ├── rag.py
    └── search.py

agent.py

负责:

决策。


runtime.py

负责:

执行Tool Call。


tools/

负责:

具体功能。

这样以后增加工具:


weather.py
database.py
email.py
browser.py

不会影响Agent核心逻辑。


十六、Agent最重要的安全问题

这里必须特别注意:

不要让本地LLM拥有无限系统权限。

例如千万不要直接:


os.system(
    llm_generated_command
)

因为模型可能生成:


rm -rf /

或者其他危险命令。


十七、正确的Tool设计原则

不要给:


execute_any_command()

这种无限权限工具。

应该设计成:


read_file()
list_files()
search_document()
calculate()

限制:


允许访问目录:

/home/user/project/

而不是:


整个磁盘

这叫:

Least Privilege(最小权限原则)


十八、Agent执行流程完整示例

用户:

帮我看看项目里有没有README,如果有就总结一下。

第一步:


User
 ↓
LLM

第二步:

LLM决定:


需要查看文件

第三步:


list_files()

得到:


main.py
README.md
requirements.txt

第四步:


read_file("README.md")

第五步:

得到:


README内容

第六步:


README
 ↓
LLM

第七步:


总结项目

最终:


项目主要使用:

Python
FAISS
llama.cpp
FastAPI

十九、Agent + RAG + llama.cpp

现在把整个专栏前面的内容全部串起来。


                         用户
                           ↓
                        Agent
                           ↓
                     本地Llama
                           ↓
              ┌────────────┼────────────┐
              ↓            ↓            ↓
           RAG Tool     File Tool    Calc Tool
              ↓            ↓            ↓
       BM25 + FAISS      文件系统     Calculator
              ↓            ↓            ↓
           Reranker        结果         结果
              └────────────┼────────────┘
                           ↓
                         Llama
                           ↓
                         答案

这时候已经具备:


知识检索
+
工具调用
+
任务规划
+
结果分析

二十、Agent和传统Chatbot的区别

能力 Chatbot Agent
文本回答
知识库检索 可选
工具调用
多步骤任务
文件操作
自动决策 有限
任务循环

所以:


LLM
 ↓
Chatbot

进一步:


LLM + RAG
 ↓
Knowledge Assistant

再进一步:


LLM + RAG + Tools + Loop
 ↓
AI Agent

二十一、Agent并不等于“让模型自由发挥”

这是开发Agent时一个非常容易出现的误区。

一个可靠Agent应该是:


明确工具
+
明确参数
+
明确权限
+
明确执行流程
+
明确停止条件

而不是:


把电脑权限全部交给LLM

工业级Agent真正关注的不是:

模型能不能自己思考。

而是:

模型能否在受控环境中可靠完成任务。


二十二、什么时候应该使用Agent?

并不是所有任务都需要Agent。

例如:

用户:

什么是Transformer?

直接:


Llama

就够了。

用户:

根据我的PDF回答问题。

使用:


RAG

更合适。

用户:

搜索我的知识库,然后读取指定文件,再计算结果,最后生成报告。

这时候才真正适合:


Agent

因此:


简单问答
 ↓
LLM

知识问答
 ↓
RAG

复杂任务
 ↓
Agent

二十三、本篇总结

这一篇我们完成了从:


本地LLM

到:


本地AI Agent

的关键升级。

核心知识:

1. Agent


LLM + Tools + Loop

2. Tool Calling


LLM
 ↓
选择工具
 ↓
参数
 ↓
程序执行
 ↓
结果
 ↓
LLM

3. Agent Runtime

负责:


解析Tool Call
 ↓
执行工具
 ↓
返回结果

4. RAG Tool

把之前的:


BM25
+
FAISS
+
Reranker

封装成Agent可以调用的工具。


二十四、现在我们的LlamaAI已经变成什么了?

回顾整个专栏:


第1篇
认识本地AI

↓

第2篇
编译llama.cpp

↓

第3篇
运行GGUF模型

↓

第4篇
CUDA GPU加速

↓

第5篇
OpenAI兼容API

↓

第6篇
RAG知识库

↓

第7篇
BM25 + FAISS + Reranker

↓

第8篇
AI Agent

现在已经形成:


                 Local AI
                    │
        ┌───────────┴───────────┐
        ↓                       ↓
       LLM                     RAG
        │                       │
   llama.cpp             BM25 + FAISS
        │                       │
      CUDA                  Reranker
        │                       │
        └───────────┬───────────┘
                    ↓
                  Agent
                    │
              Tool Calling
                    │
        ┌───────────┼───────────┐
        ↓           ↓           ↓
      File         Code       Search

这已经是一个完整的本地AI应用基础架构。


下一篇预告

《llama.cpp性能优化实战:从显存、KV Cache到Token/s》

前面我们一直在追求:

让模型跑起来。

下一篇开始追求:

让模型跑得更快、更省显存、更稳定。

将重点分析:

  • Token/s到底是什么
  • Prompt Processing和Token Generation
  • KV Cache原理
  • Context Size对显存的影响
  • Batch Size如何影响性能
  • GPU Offload
  • Flash Attention
  • Quantization量化
  • CPU线程优化
  • 多用户并发
  • 如何使用 nvidia-smi 和性能指标定位瓶颈

最终我们会建立一套完整的:


模型
 ↓
显存
 ↓
CUDA
 ↓
KV Cache
 ↓
Batch
 ↓
Token/s

本地LLM性能优化体系。

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐