llm-agent
agent-iot
输入构成
获取设备的属性快照信息和控制信息(设备说明书、API文档),作为 system prompt。
可使用function calling让输出更加规范,调用具体的函数。
用户的输入作为userPrompt,意图。
Scene场景
- 用户情景、场景设置:经典场景 ifttt 规则引擎
- 主动智能:(JMQ事件感知 DUCC配置规则)
- 按照用户的使用习惯,自动生成场景(需要开放给用户)
语义层标准化
定义与底层协议无关的通用指令模型,包括:
- 操作类型:
GET
(查询)、SET
(设置)、EXECUTE
(执行服务) - 目标标识:设备ID + 属性/服务ID(如
AC-001/targetTemp
) - 参数格式:JSON/二进制编码的统一数据表达(如
{"value":25}
)
1 | {"op":"SET","path":"AC-001/targetTemp","params":{"value":25}} |
为了加快响应,应当进一步简化。。。?
开灯:
- 很多盏灯,要开哪一盏?如果查询到用户操作的品类对应有多台设备,应当询问用户对哪一台进行操作,然后从用户的补充说明中提取deviceName或者roomName这样的字段,然后匹配到具体的设备id,就能返回对应的控制指令。然后调用小家平台控制API进行控制。
- 没有灯。如果用户操作的品类没有对应的设备,应当以友好语气回复用户,并给出一定的建议(是否需要跳转购买)。
Function Calling
source:10分钟讲清楚 Prompt, Agent, MCP 是什么
System Prompt: 模型扮演的角色,使用什么方式回复,用户只需要关注真正需要说的话(User Prompt)。
AI Agent: AutoGPT 会把函数用法和功能描述、AI的回复格式转化为SystemPrompt,把SystemPrompt连同用户请求UserPrompt发送给模型。模型生成函数的调用信息,AutoGPT随后去调用函数并返回结果。这样在模型、工具、用户之间传话的程序叫做 Agent。这些提供调用的函数或者服务叫做 Agent Tools。AI总归是概率模型,发现返回格式不对会进行重试,典型例子Cline。
Function Calling: 统一格式,规范描述。将函数用法和功能描述转化成类似如下的固定JSON格式,因此 System Prompt中的这一部分可以删去。AI 使用工具时的回复也都依照相同的格式,因此可以实现有针对性训练,并且AI服务器端自己就能检测到格式错误,实现用户无感的服务端重试,节省 prompt。缺点是各家模型api格式不统一,因此跨模型能力一般。
1 | // 调用信息 |
.png)
- 核心思想:允许 LLM 在推理过程中,识别用户请求中需要调用外部工具或 API 来完成特定任务的意图,然后以结构化格式(通常是 JSON)输出一个包含所需调用函数名称和参数的请求。LLM 本身并不执行函数,而是由应用程序接收这个请求,调用对应的外部函数/API,并将执行结果返回给 LLM(通常作为后续对话的上下文),最终由 LLM 整合结果并生成面向用户的自然语言回复,或者LLM继续生成结构化调用信息,Agent继续调用API重复上述步骤。
- 解决的问题:
- 功能局限性:LLM 本质是文本生成器,无法直接执行现实世界的操作(如查数据库、发邮件、查天气、运行代码、数学计算)。
- 动态信息获取:获取需要实时计算或查询外部系统才能得到的信息(如当前股价、天气、账户余额)。
- 状态改变:执行需要改变外部系统状态的操作(如创建日历事件、发送邮件、下订单)。
- 精确性要求高的操作:对于需要精确执行、不能依赖 LLM 自由发挥的任务(如数据库查询)。
- 工作流程:
- 用户请求:用户提出一个可能需要调用外部功能的请求(如 “预订下周一上午10点的会议室” 或 “旧金山现在的天气怎么样?”)。
- 模型推理与函数调用检测:LLM 分析请求,判断是否需要调用函数以及调用哪个函数。如果需要,它生成一个结构化的函数调用请求(函数名 + 参数)。
- 应用程序执行函数:应用程序(或代理框架)接收到 LLM 输出的函数调用请求,解析它,并调用相应的后端函数或 API,传入参数。
- 获取函数结果:后端函数/API 执行,返回结果(可能是数据、状态码、错误信息等)。
- 结果整合与生成回复:应用程序将函数执行结果作为上下文信息,连同原始的对话历史(或新的用户消息)一起再次发送给 LLM。
- 最终回复:LLM 理解函数执行结果,生成自然语言回复给用户(如 “已为您预订了X会议室” 或 “旧金山现在是晴天,22摄氏度”)。
- 关键组件:
- 支持 Function Calling 能力的 LLM(如 GPT-3.5-turbo, GPT-4, Claude, 部分开源模型)。
- 应用程序逻辑(解析 LLM 的函数调用请求,执行函数/API,管理上下文)。
- 预定义的可调用函数/API 列表及其描述(名称、功能描述、参数及其类型、是否必需)。
- 典型应用场景:
- 智能助理执行操作:发邮件、订日历、查待办事项、控制智能家居。
- 数据查询助手:根据自然语言查询数据库或 API(如 “上季度华东区的销售总额是多少?”)。
- 代码解释器/工具使用:执行数学计算、绘图、运行 Python 代码片段。
- 旅行规划:搜索航班、酒店、景点信息。
- 实时信息查询:股票、天气、新闻、汇率。
以上是Agent和LLM之间的交互。下面介绍 API Agent之间的交互。
MCP:Agent与Tools交互
MCP: 模型上下文协议。解决的是 Agent Tools 和 AI Agent 交互的问题。本地可以直接在同一个进程里调用,但是随着时间的推移,发现有些tool功能是通用的,为了复用代码,就可以让多个Agent调用同一个tool服务。
MCP Server——运行Tool的服务,MCP Client——Agent。
MCP用来规定他俩之间的通信格式,以及MCP Server需要提供的接口(list tools,tool desc,etc.)
MCP Server可以直接提供数据,提供类似文件读写的服务:Resources,可以提供提示词模板:Prompts
Server和Client可以通过标准输出stdio、http等方式通信
.png)
标准流程:
- 发送 User Prompt,“女朋友肚子疼怎么办”
- MCP Client 从 Server 获取tool的基本信息,转化成 Function Calling 或者 System Prompt 格式,附带 User Prompt 一并发送给模型,模型返回调用信息。这里最核心的就是把函数的API和API文档。
- MCP Client 通过模型返回的调用信息,请求 MCP Server,随后将 HTTP页面转发给 AI 模型,AI模型据此回复
.png)
1 | curl https://api.deepseek.com/chat/completions \ |
RAG (检索增强生成)
- 核心思想:将大型语言模型(LLM)的生成能力与外部知识源(通常是向量数据库)的检索能力结合起来。在生成答案之前,先从外部知识库中检索与用户查询最相关的信息片段(chunks),然后将这些信息片段和原始查询一起提供给 LLM,让 LLM 基于这些最新、特定、可信的上下文信息生成回答。
- 解决的问题:
- 知识局限性/陈旧性:LLM 的知识截止于其训练数据。RAG 允许模型访问并利用训练后产生的最新信息或模型训练数据中未包含的专有/特定领域信息。
- 事实准确性/幻觉:通过提供可靠的上下文来源,引导 LLM 基于事实而非凭空想象(幻觉)生成答案。
- 溯源:可以追踪生成答案的依据(来自哪个检索到的文档片段)。
- 工作流程:
- 用户查询:接收用户输入的问题。
- 检索:将用户查询嵌入(embed)成向量,在预先构建好的向量数据库中进行相似性搜索,找出最相关的文档片段(通常是 Top-K)。
- 增强提示:将检索到的相关片段(上下文)与用户的原始查询组合成一个新的、信息更丰富的提示(Prompt)。
- 生成:将这个增强后的提示输入给 LLM。
- 响应:LLM 基于提供的上下文生成最终的答案。
- 关键组件:
- 文本嵌入模型(Embedding Model)
- 向量数据库(Vector Database)
- 大型语言模型(LLM)
- 检索策略(如 Top-K, MMR)
- 典型应用场景:
- 基于公司内部文档(手册、产品文档、会议记录)的智能问答系统。
- 需要最新信息的问答(如新闻摘要、市场报告)。
- 需要引用特定来源的客服聊天机器人。
- 学术研究助手(搜索论文库回答问题)。
RAG vs Function Calling: 核心对比
- RAG 是给 LLM “喂知识”:解决 “LLM 不知道什么” 的问题。通过检索外部信息源提供相关上下文,让生成更准确、更新、更相关。
- Function Calling 是让 LLM “用工具”:解决 “LLM 不能做什么” 的问题。通过检测意图并输出结构化请求,让 LLM 能够触发外部工具执行操作或获取 LLM 自身无法计算/访问的动态信息。强调动作
- 强大的AI应用 = RAG + Function Calling + LLM:最先进的 LLM 应用架构通常会将两者结合,甚至与 Agent(能自主规划、调用工具、迭代的 LLM 驱动模块)的概念融合,打造出真正强大、知识丰富且能执行实际任务的 AI 系统。
特性 | RAG (检索增强生成) | Function Calling (函数调用) |
---|---|---|
主要目的 | 增强知识- 提供最新、特定领域的上下文信息给 LLM 用于生成。 | 增强功能- 让 LLM 能够触发外部工具/API 执行操作或获取动态数据。 |
核心操作 | 检索信息片段 ->注入上下文-> LLM 生成答案。 | LLM检测意图->输出结构化调用请求->外部执行-> LLM整合结果生成回复。 |
LLM 角色 | 知识消费者(利用提供的上下文生成答案)。 | 意图检测器 & 结果解释器(不直接执行功能)。 |
输入增强 | 是。将检索到的文本作为额外上下文输入给 LLM。 | 间接是。函数执行的结果可作为后续 LLM 调用的上下文输入。 |
输出形式 | 自然语言文本(最终答案)。 | 结构化数据(函数调用请求 JSON)或自然语言文本(最终整合后的答案)。 |
依赖外部 | 向量数据库/文档存储(存储和检索知识)。 | 后端函数/API/服务(执行具体操作或提供动态数据)。 |
解决痛点 | 知识过时、领域知识缺失、幻觉、需要溯源。 | 无法执行操作、无法获取实时数据、无法精确操作外部系统。 |
典型输出 | “根据[文档Y]第X节,… 的答案是…” | {"name": "get_weather", "arguments": {"location": "San Francisco"}} (或整合后的 “旧金山天气晴,22°C”) |
协同使用
RAG 和 Function Calling不是互斥的,而是互补的,经常在同一个复杂的 LLM 应用中结合使用:
- 使用 Function Calling 执行检索:你可以定义一个
search_knowledge_base(query: string)
的函数。当用户提问时,LLM 可以决定调用这个函数。应用程序执行该函数(本质上就是进行一次 RAG 的检索步骤),将检索到的文档片段作为结果返回给 LLM。LLM 再基于这些片段生成最终回答。这相当于用 Function Calling 的机制来实现 RAG 流程。 - 在 RAG 流程中使用 Function Calling 获取必要信息:假设你的 RAG 系统需要回答一个需要实时数据的复杂问题(如 “基于我们最新的产品手册和当前的库存情况,我能在北京最快什么时候收到 Model X?”)。LLM 在分析增强后的提示(包含手册片段)时,可能发现需要当前库存和物流信息,于是输出一个调用
check_inventory(product_id)
和get_shipping_estimate(location)
的请求。应用程序执行这些函数,将结果再次提供给 LLM。LLM 结合手册片段、库存数据和物流信息生成最终答案。 - Function Calling 执行操作,RAG 提供操作依据:用户说 “请把这份报告的主要发现摘要邮件发给项目组”。LLM 可能先调用 RAG 函数
summarize_document(document_id)
获取摘要(RAG 部分),然后调用send_email(recipients, subject, body)
函数,并将摘要作为邮件正文内容(Function Calling 部分)。
现有框架
langchain4j 支持function calling,@Tool
注解标记Tools方法,可以在注解值里标注此函数的用途。@P注解方法的参数,