一篇入门Agent

Agent是什么?

很多书把Agent这个概念写得很抽象:感知、决策、执行......一串术语下来,让人摸不着头脑。

其实,从实操层面,Agent可以简单理解为:

Agent=自主决策的循环+可调用的工具+本地知识库或数据库+边界

其中,本地知识库或数据库并不是所有Agent的必须项,但在很多业务场景中,它能让Agent的回答更精准、更贴合个人或企业需求。

自主决策的循环,是指拥有大模型的循环语句,比如:

复制代码
def run_agent(task: str, max_steps: int = 5):
    messages = [{"role": "user", "content": task}]

    for step in range(max_steps):
        # 1. 让模型决定下一步:直接回答,还是调用工具
        response = call_llm(messages)

        # 2. 如果模型要调用工具
        if response.tool_call:
            tool_name = response.tool_call.name
            args = response.tool_call.args
            result = TOOLS[tool_name](**args)      # 执行工具
            messages.append(response.message)       # 记录模型决策
            messages.append({"role": "tool", "content": result})  # 回传结果
        else:
            # 3. 模型给出最终答案,结束
            return response.content

    return "达到最大步数,未完成"

在上面循环代码中,call_llm就是在调用大模型。

工具可以是系统自带的,比如计算器,也可以是自己写的程序。

Agent的设计大部分时候是为了实现业务需求,或者贴合我们的个人需求,简化日常操作,比如收集信息、发送邮件、查找信息等。这就需要我们个人的知识库或者本地数据库,通过RAG来获取更精准的回复。

大模型本身是有局限性的。

它本质上做的是概率生成,擅长语义逻辑和连贯表达,但并不保证事实准确性和计算精确性。

面对复杂的计算或者不了解的事实,它可能会编造内容,也就是出现AI幻觉。

因此,Agent的设计需要设置边界条件,比如邮件它写好了不能直接发出去,需要人工复核。

可以这样理解:

  • 大模型赋予了循环一个大脑,拥有大模型的循环可以理解为能决策的大脑。
  • 工具是手,通过工具,大脑能和现实世界产生交互。
  • 本地数据库/知识库就像是外部记忆或私有经验,让智能体的言行更符合现实期望。
  • 安全边界就像是行为准则,明确哪些行为不能越界,哪些操作必须人工确认。

这四者使得我们可以使用自然语言给程序下指令,就能获得我们期望的结果,这就是智能体Agent。

是不是所有加了AI的程序都可以称为Agent?

不是。

必须是控制流由LLM自主决定的,才能称为Agent。

像有输入、输出,也内置了AI,但是流程固定,只能称为工具,或者AI工作流。

复制代码
┌──────────────────────────────────────────────┐
│              AI 工作流:流程固定              │
├──────────────────────────────────────────────┤
│                                              │
│   用户输入                                    │
│      │                                       │
│      ▼                                       │
│   步骤 1:调用 LLM(摘要/分类/抽取)           │
│      │                                       │
│      ▼                                       │
│   步骤 2:调用工具/API                        │
│      │                                       │
│      ▼                                       │
│   步骤 3:固定后处理                          │
│      │                                       │
│      ▼                                       │
│   输出结果                                    │
│                                              │
│   控制流:开发者写死                          │
│   LLM 角色:只参与其中某一步                  │
│                                              │
└──────────────────────────────────────────────┘

┌──────────────────────────────────────────────┐
│           Agent:控制流由 LLM 决定            │
├──────────────────────────────────────────────┤
│                                              │
│   用户输入                                    │
│      │                                       │
│      ▼                                       │
│   ┌──────────────────────────────┐           │
│   │        LLM 决策循环           │           │
│   │                              │           │
│   │   LLM 判断下一步:            │           │
│   │   ├─ 直接回答 ──► 输出答案    │           │
│   │   └─ 调用工具 ──► 执行工具    │           │
│   │                     │        │           │
│   │                     ▼        │           │
│   │              工具结果回传     │           │
│   │                     │        │           │
│   │                     └────────┘           │
│   └──────────────────────────────┘           │
│                                              │
│   工具集:搜索/数据库/计算/发邮件             │
│   知识库:本地数据库 / RAG                    │
│   边界:只读、人工复核、白名单                │
│                                              │
└──────────────────────────────────────────────┘

使用Openmanus构建一个最小化Agent

Openmanus是一个Agent开发框架,它内置了很多工具和模型调用命令,使得Agent开发更加简单易行。

以获取我本地的个人支出数据,最终回答"2024年度的总支出"为例。

1. 系统与版本要求

操作系统:Windows

Python:必须3.12(Openmanus要求>=3.12)

包管理:推荐uv(更快,自带python版本管理)

2. 创建虚拟环境(Python 3.12)

复制代码
# 用 uv 创建 3.12 环境(uv 会自动准备 3.12,无需手动安装)
uv venv --python 3.12

# 激活(Windows Git Bash)
source .venv/Scripts/activate

# 确认版本
python --version        # 应为 Python 3.12.x

3. 获取Openmanus开源代码、安装依赖

复制代码
git clone https://github.com/FoundationAgents/OpenManus.git
cd OpenManus
uv pip install -r requirements.txt

4. 配置 LLM

4.1 复制配置模板
复制代码
cp config/config.example.toml config/config.toml
4.2 填写LLM段

以deepseek为例,

复制代码
[llm]
model = "deepseek-chat"                    # 必须支持 function calling
base_url = "https://api.deepseek.com"
api_key = "sk-你的密钥"
max_tokens = 8192
temperature = 0.0

5. 启动验证

复制代码
python main.py

成功标志:出现 Enter your prompt:

输入:帮我计算3*7+5

提示:✨ Manus's thoughts: I'll calculate that for you.

🧰 Tools being prepared: 'python_execute'

🔧 Tool arguments: {"code": "print(3*7+5)"}

🎯 Tool 'python_execute' completed its mission! Result: 26

说明框架、LLM、工具调用链路全部跑通。

6. 接入本地PostgreSQL

6.1 编写数据库工具

新建app/tool/query_expense.py:

复制代码
from app.tool.base import BaseTool, ToolResult
import psycopg2
import os


class QueryExpense(BaseTool):
    """查询本地 PostgreSQL 支出数据库的工具。"""

    name: str = "query_expense"
    description: str = (
        "查询本地 PostgreSQL 数据库中的支出记录。"
        "输入一条 SQL SELECT 语句,返回查询结果。"
        "可用表(均在 public schema):"
        "ods_records_1(date, type, category, amount) ------ 2024 年数据;"
        "ods_records_2(date, type, category, amount) ------ 2023 年数据;"
        "records2(date, type, category, amount) ------ 2023 年数据(副本)。"
        "其中 amount 为金额,category 为分类,type 为类型,date 为日期(DATE 类型)。"
        "仅接受 SELECT 查询。"
    )
    parameters: dict = {
        "type": "object",
        "properties": {
            "sql": {"type": "string", "description": "要执行的 SELECT 查询语句"}
        },
        "required": ["sql"],
    }

    async def execute(self, sql: str) -> ToolResult:
        if not sql.strip().upper().startswith("SELECT"):
            return ToolResult(error="仅允许执行 SELECT 查询")

        conn = None
        try:
            conn = psycopg2.connect(
                dbname=os.getenv("PG_DBNAME"),
                user=os.getenv("PG_USER"),
                password=os.getenv("PG_PASSWORD"),
                host=os.getenv("PG_HOST", "localhost"),
                port=os.getenv("PG_PORT", "5432"),
                client_encoding=os.getenv("PG_CLIENT_ENCODING", "UTF8"),
            )
            cur = conn.cursor()
            cur.execute(sql)
            rows = cur.fetchall()
            columns = [desc[0] for desc in cur.description] if cur.description else []

            if not rows:
                return ToolResult(output="查询结果为空")

            output_lines = [" | ".join(columns)]
            output_lines.append("-" * 40)
            for row in rows:
                output_lines.append(" | ".join(str(v) for v in row))

            return ToolResult(output="\n".join(output_lines))

        except psycopg2.Error as e:
            return ToolResult(error=f"数据库错误:{e}")
        except Exception as e:
            return ToolResult(error=f"执行失败:{e}")
        finally:
            if conn:
                conn.close()
6.2 注册工具

app/tool/__init__.py 末尾加:

复制代码
from app.tool.query_expense import QueryExpense

app/agent/manus.py 里,找到 ToolCollection(...),加入:

复制代码
from app.tool.query_expense import QueryExpense

self.available_tools = ToolCollection(
    ...,
    QueryExpense(),    # 加这行
)
6.3 安装驱动
复制代码
uv pip install psycopg2-binary
6.4 配置数据库连接
复制代码
export PG_DBNAME="你的库名"
export PG_USER="postgres"
export PG_PASSWORD="你的真实密码"
export PG_HOST="localhost"
export PG_PORT="5432"

7. 最终结果

复制代码
Enter your prompt: 查一下 2024 年支出

Agent自动生成SQL并执行返回了我想要的结果。

在这个数据查询的例子中,有拥有大模型的循环、工具调用、数据库接入就是一个比较完整的、最小化可行的智能体。

相关推荐
余醉 | dtminer1 小时前
3337 OTU×999置换:群落构建mBio 高分沉积物
开发语言·r语言·微生物学
java1234_小锋1 小时前
【技术专题】HTML5 网页技术 - HTML5 表格标签
前端·html·html5
白杨尚青1 小时前
C++入门篇(十八):模板进阶——非类型参数、特化全家桶与分离编译(收官篇)
开发语言·c++·笔记·模板·偏特化·分离编译
silvamux_1 小时前
4款新模型商务邮件翻译横评:0.98到0.46
android·java·javascript
雪芽蓝域zzs1 小时前
JS 项目转 TS 项目(Vue3 + 若依这类后台项目)完整改造清单
前端·vue.js
定栓1 小时前
Webpack迁到Vite第四节:SVG 图标系统
前端·webpack·node.js
qetfw1 小时前
Bash 内置与外部命令:type、command 与 builtin 验证
linux·开发语言·bash
Dovis(誓平步青云)2 小时前
车辆进入隧道后信号断开,座舱旅程怎样补回事件
java·开发语言·前端·数据库·电脑