AI 编程真正有意思的地方,不是让大模型帮你写几行代码,而是让它拥有知识、记忆和工具,能够独立完成一个真实任务。

很多开发者第一次接触大模型,通常从聊天机器人开始:

用户提问 → 调用大模型 → 返回答案

这种应用开发简单,但也很容易陷入同质化。模型只能根据提示词生成文字,无法查询企业数据、操作业务系统,更不能可靠地完成多步骤任务。

如果把下面三项技术组合起来,效果会完全不同:

  • RAG:让 AI 使用你的私有知识
  • Function Calling:让 AI 调用真实工具
  • Agent Workflow:让 AI 自主规划并执行任务

本文将用一个“智能技术助手”的案例,介绍如何让 AI 从聊天工具升级成真正能干活的智能体。


一、我们要做什么?

假设需要开发一个企业内部技术助手,它能够:

  1. 查询项目文档和历史故障记录;
  2. 分析用户描述的问题;
  3. 调用日志查询、工单创建等工具;
  4. 根据工具返回结果继续推理;
  5. 最终输出解决方案。

用户只需要输入:

订单服务今天频繁超时,帮我检查原因。如果属于线上故障,请创建工单。

智能体会自动完成:

理解问题
  ↓
检索订单服务相关文档
  ↓
调用日志查询工具
  ↓
分析异常信息
  ↓
判断故障等级
  ↓
创建工单
  ↓
返回处理结果

这已经不是普通问答,而是一个小型的 AI 自动化系统。


二、RAG:给 AI 安装“外接知识库”

大模型虽然知道很多通用知识,但它不知道公司内部接口、项目架构和故障处理流程。

RAG(Retrieval-Augmented Generation,检索增强生成)的核心思想是:

先从知识库中检索相关内容,再把检索结果交给大模型回答。

一个典型流程如下:

用户问题
  ↓
生成向量
  ↓
从向量数据库检索相似文档
  ↓
组合问题与文档
  ↓
交给大模型生成答案

1. 文档向量化

下面用伪代码展示基本过程:

documents = [
    "订单服务使用 Redis 保存热点商品库存。",
    "订单接口超时时,应首先检查数据库连接池。",
    "线上故障达到 P1 级别时,需要立即创建工单。"
]

for document in documents:
    vector = embedding_model.embed(document)

    vector_database.insert({
        "content": document,
        "vector": vector
    })

这里的 Embedding 模型会把文字转换成一组数字。语义越接近的文本,其向量距离通常越近。

2. 根据问题检索知识

def search_knowledge(question):
    question_vector = embedding_model.embed(question)

    return vector_database.search(
        vector=question_vector,
        top_k=3
    )

当用户询问“订单接口为什么超时”时,即使文档中没有完全相同的句子,也可以检索到“数据库连接池”“Redis”“订单服务”等相关内容。

这正是向量检索相比传统关键词搜索更吸引人的地方:它搜索的是语义,而不只是文字。


三、Function Calling:让 AI 从“会说”变成“会做”

RAG解决了知识问题,但智能体仍然只能回答,无法真正操作系统。

Function Calling 可以让开发者把程序中的函数描述给模型,由模型判断应该调用哪个函数,以及需要传入什么参数。

例如,我们为智能体提供两个工具:

tools = [
    {
        "name": "query_service_logs",
        "description": "查询指定服务在某个时间范围内的错误日志",
        "parameters": {
            "type": "object",
            "properties": {
                "service_name": {
                    "type": "string",
                    "description": "服务名称"
                },
                "minutes": {
                    "type": "integer",
                    "description": "查询最近多少分钟"
                }
            },
            "required": ["service_name", "minutes"]
        }
    },
    {
        "name": "create_incident_ticket",
        "description": "创建线上故障工单",
        "parameters": {
            "type": "object",
            "properties": {
                "title": {"type": "string"},
                "level": {
                    "type": "string",
                    "enum": ["P1", "P2", "P3"]
                },
                "description": {"type": "string"}
            },
            "required": ["title", "level", "description"]
        }
    }
]

模型收到用户问题后,可能不会直接返回文字,而是生成结构化调用请求:

{
  "name": "query_service_logs",
  "arguments": {
    "service_name": "order-service",
    "minutes": 30
  }
}

程序执行对应函数:

def query_service_logs(service_name, minutes):
    return {
        "service": service_name,
        "error_count": 236,
        "main_error": "Database connection pool exhausted",
        "average_latency": "4.8s"
    }

再把结果交回模型,它就能继续分析:

订单服务在最近30分钟出现236次错误,
主要原因为数据库连接池耗尽,
平均响应时间达到4.8秒。

如果模型判断达到线上故障标准,还可以继续调用创建工单函数。


四、最关键的技术:Agent 推理循环

真正让智能体显得“聪明”的,并不是某一次模型调用,而是循环。

智能体需要不断重复以下过程:

观察 → 思考 → 行动 → 获取结果 → 再思考

这类机制也经常被称为 Agent Loop。

def run_agent(user_input):
    messages = [
        {
            "role": "system",
            "content": """
你是一名高级运维工程师。
请结合知识库和可用工具处理问题。
涉及高风险操作时必须先说明原因。
"""
        },
        {
            "role": "user",
            "content": user_input
        }
    ]

    for step in range(8):
        response = llm.chat(
            messages=messages,
            tools=tools
        )

        if response.has_tool_call():
            tool_name = response.tool_name
            arguments = response.arguments

            tool_result = execute_tool(
                tool_name,
                arguments
            )

            messages.append(response.to_message())
            messages.append({
                "role": "tool",
                "name": tool_name,
                "content": json.dumps(tool_result)
            })

            continue

        return response.content

    return "任务执行步骤超过限制,已停止。"

这段代码虽然不长,却包含了智能体最核心的工作方式:

  1. 模型分析当前信息;
  2. 模型决定是否调用工具;
  3. 程序执行工具;
  4. 工具结果返回给模型;
  5. 模型结合新信息继续判断;
  6. 直到生成最终答案。

普通聊天应用通常只调用一次模型,而智能体可能调用多次模型和多个工具。这也是两者能力差距的来源。


五、加入“记忆”,让 AI 越用越懂你

如果每次对话结束后全部清空,智能体很难形成连续体验。

可以把记忆分成三类。

1. 短期记忆

保存当前会话的上下文:

conversation_memory.append({
    "role": "user",
    "content": user_input
})

2. 长期记忆

保存用户偏好和稳定信息:

{
  "user_id": "10086",
  "preferences": {
    "language": "Python",
    "response_style": "先给结论,再解释原因",
    "deployment": "Docker + Linux"
  }
}

3. 经验记忆

记录以前解决过的问题:

{
  "problem": "订单服务数据库连接池耗尽",
  "solution": "检查慢查询,并临时提高连接池上限",
  "result": "服务在5分钟内恢复",
  "confidence": 0.92
}

下次遇到类似故障时,系统可以先检索历史经验,再决定解决方案。

这里有一个很实用的技巧:

不要把所有历史消息都发送给模型,而是把历史内容压缩成摘要,并通过向量检索召回真正相关的记忆。

否则上下文会越来越长,响应速度和调用成本也会持续上升。


六、让智能体更可靠:结果校验与安全边界

AI Agent 最大的风险并不是“答错一句话”,而是“执行错一个操作”。

例如:

  • 删除了错误的数据;
  • 给错误的客户发送邮件;
  • 重复创建多张工单;
  • 执行了模型虚构出的参数;
  • 陷入无限工具调用循环。

因此,生产系统至少要加入以下保护。

1. 参数校验

def validate_tool_arguments(tool_name, arguments):
    if tool_name == "query_service_logs":
        if arguments["minutes"] < 1:
            raise ValueError("查询时间必须大于0")

        if arguments["minutes"] > 1440:
            raise ValueError("单次最多查询24小时")

2. 高风险操作需要确认

HIGH_RISK_TOOLS = {
    "delete_database",
    "restart_production_service",
    "send_external_email"
}

if tool_name in HIGH_RISK_TOOLS:
    return {
        "status": "waiting_confirmation",
        "message": "该操作需要用户确认"
    }

3. 限制最大执行步数

MAX_AGENT_STEPS = 8

4. 防止重复执行

execution_key = hash(tool_name + json.dumps(arguments))

if execution_key in executed_operations:
    raise RuntimeError("检测到重复工具调用")

5. 要求模型提供证据

输出答案时,可以要求模型区分事实和推测:

请在最终结论中分别列出:

1. 已确认事实;
2. 基于日志的推断;
3. 尚未验证的可能原因;
4. 已经执行的操作。

这个设计看似简单,却能显著减少“AI 一本正经地胡说”的情况。


七、一个更独特的方向:双智能体交叉验证

如果希望项目更有技术亮点,可以增加一个 Reviewer Agent。

第一个智能体负责解决问题:

执行智能体:检索资料、调用工具、给出解决方案

第二个智能体负责检查:

审查智能体:检查证据、参数、安全性和结论

示例代码:

solution = executor_agent.run(task)

review = reviewer_agent.run({
    "task": task,
    "solution": solution,
    "requirements": [
        "结论是否有证据支持",
        "是否遗漏安全风险",
        "是否执行了未经授权的操作",
        "工具返回结果是否被正确理解"
    ]
})

if review["passed"]:
    return solution

return executor_agent.revise(
    original_solution=solution,
    review=review
)

这种模式类似软件开发中的“编码 + Code Review”。

它无法保证绝对正确,却能减少单个模型直接做出错误决定的概率,特别适用于自动生成报告、分析故障、处理数据等场景。


八、推荐的项目架构

一个具备可维护性的智能体项目,可以采用以下结构:

ai-agent/
├── api/                 # 对外接口
├── agents/              # 智能体定义
│   ├── executor.py
│   └── reviewer.py
├── tools/               # 工具实现
│   ├── log_tool.py
│   └── ticket_tool.py
├── rag/                 # 知识检索
│   ├── embedding.py
│   └── retriever.py
├── memory/              # 长短期记忆
├── prompts/             # 提示词模板
├── security/            # 权限和参数校验
├── observability/       # 日志、链路和成本监控
└── main.py

不建议把提示词、工具调用和数据库代码全部写在同一个文件里。随着工具数量增加,这种写法会迅速失控。


九、为什么 AI Agent 值得程序员学习?

传统软件的逻辑通常是确定的:

if condition:
    do_something()

智能体应用则把部分决策交给模型:

模型根据目标、上下文和工具能力,决定下一步行动

这并不意味着程序员不再重要。恰恰相反,开发者需要负责更多关键工作:

  • 设计模型可以使用的工具;
  • 建立可靠的知识检索系统;
  • 控制权限和执行边界;
  • 处理模型的不确定性;
  • 记录智能体的决策过程;
  • 评估输出质量与调用成本。

未来真正有竞争力的 AI 应用,大概率不是简单套一个聊天框,而是把大模型嵌入具体业务流程。


十、总结

一个能真正落地的 AI 智能体,通常由四个核心部分组成:

大模型:负责理解和推理
RAG:负责提供私有知识
Tools:负责执行真实操作
Agent Loop:负责规划并持续推进任务

再进一步加入:

Memory + Reviewer + Permission + Observability

就能从一个演示级聊天机器人,逐渐演进为可用于真实场景的智能系统。

AI 编程最令人兴奋的地方,不是让模型代替程序员写代码,而是让程序第一次拥有了一定程度的理解、判断和行动能力。

如果你正在寻找一个适合练手、适合写进简历,同时又具有技术深度的 AI 项目,那么“RAG + Function Calling + Agent Workflow”会是一个非常值得投入的方向。


AI妙回恋爱聊天助手|上传聊天截图生成回复与开场白AI妙回面向用户:上传微信、QQ、小红书聊天截图,生成3条定制恋爱回复;根据资料生成开场搭讪话术;还能向AI恋爱顾问咨询关系与个人提升问题。https://www.saycoding.com/

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐