基于对话式任务执行的AI智能体框架:构建可控可解释的LLM应用
2026/9/21 0:55:46 网站建设 项目流程

最近在技术社区里,一个名为“喜欢吗?我也喜欢~”的项目悄然走红。初看这个标题,你可能会以为它又是一个娱乐或社交应用。但如果你点进去,会发现它其实是一个基于大语言模型(LLM)的、高度可定制的智能对话与任务执行框架。它之所以能引起开发者的广泛兴趣,核心在于它试图解决一个非常具体且普遍的痛点:如何让AI Agent(智能体)的交互过程更自然、更可控,并且能深度集成到开发者的工作流中

很多开发者都体验过类似AutoGPT、LangChain这样的工具,它们功能强大,但有时也让人感到“失控”——你给一个目标,它就开始“自由发挥”,过程不透明,结果难预测,调试起来更是困难。“喜欢吗?我也喜欢~”这个项目,从命名上就透露出一种拟人化的亲和力,而其设计哲学正是将复杂的Agent执行过程,转化为一场结构清晰、步骤可控、状态可见的“对话”。它不是一个黑盒,而是一个你可以随时介入、引导、修正的协作伙伴。

本文将为你深度解析这个项目。我们不会停留在表面的功能介绍,而是会深入探讨:

  1. 它到底解决了什么工程问题?与传统Agent框架相比,它的核心差异在哪里?
  2. 它的架构是如何设计的?如何理解其“对话即任务”的理念?
  3. 如何从零开始搭建和运行一个实例?我们将提供完整的代码和配置示例。
  4. 在实际使用中会遇到哪些“坑”?如何优化提示词、管理上下文长度?
  5. 它最适合哪些场景?是自动化脚本生成、数据分析,还是作为复杂系统的“AI中间件”?

无论你是想寻找一个更趁手的AI开发工具,还是对下一代人机协作界面感兴趣,这篇文章都将为你提供一份可落地、可实践的详细指南。

1. 这篇文章真正要解决的问题

在深入代码之前,我们必须先厘清一个根本问题:为什么我们需要另一个AI Agent框架?现有的工具链已经非常丰富。

关键在于“可控性”与“可解释性”的缺失。许多Agent框架的设计目标是“全自动”完成任务,这导致:

  • 过程黑盒化:Agent内部进行了多少次思考(Chain of Thought)?调用了哪些工具?决策依据是什么?开发者很难知晓。
  • 纠错成本高:一旦Agent“跑偏”,很难从中间步骤进行干预,往往需要从头开始,浪费大量的Token和计算资源。
  • 集成困难:Agent的复杂工作流难以无缝嵌入到现有的软件系统中,其状态管理和生命周期控制是个挑战。

“喜欢吗?我也喜欢~”项目(为方便叙述,后文我们称其为Liking框架)的切入点正在于此。它不追求完全的无监督自动化,而是强调“人机协同”“过程显式化”。它将一个复杂的任务分解为一系列可管理的“对话回合”,每个回合都包含清晰的输入、思考、行动和输出。开发者可以像审查日志一样审查每一个回合,也可以在任意回合插入指导或修正。

因此,本文要解决的核心问题是:如何利用Liking框架,构建一个既强大又可控的AI智能体,并将其应用于实际的开发、测试或数据分析场景中。我们将重点关注其架构思想、实操部署以及如何规避常见陷阱。

2. 基础概念与核心原理

要理解Liking,需要先掌握几个核心概念,它们共同构成了其“对话即任务”的哲学。

2.1 核心概念解析

  • Agent(智能体):在Liking中,Agent是一个具有特定目标、记忆和能力的虚拟实体。它通过与大语言模型(LLM)交互来理解和执行任务。你可以把它想象成一个拥有专业技能的虚拟员工。
  • Skill(技能):这是Agent能力的具象化。一个Skill可以是一个简单的函数(如计算器、查询天气),也可以是一个复杂的流程(如生成SQL语句并执行、调用外部API获取数据)。Liking框架的核心优势之一就是可以方便地定义和组合Skill。
  • Conversation(对话):这是Liking最核心的抽象。一个任务的一次完整执行,被建模为一场“对话”。这场对话由多个Turn(回合)组成。
  • Turn(回合):对话的基本单元。一个典型的Turn包含:
    1. User Input(用户输入):用户或系统发出的指令。
    2. Agent Thought(智能体思考):LLM根据当前上下文和可用Skill,决定下一步该做什么(内部推理)。
    3. Action(行动):执行选定的Skill,或给出最终回答。
    4. Observation(观察):Action执行后的结果(如函数返回值、API响应)。
    5. Response(响应):LLM整合Observation,生成面向用户的回复。 这个过程会循环,直到任务完成。每个Turn的状态都会被完整记录。
  • Memory(记忆):Agent的“大脑”,用于存储对话历史、任务上下文、以及从过往经验中学到的知识。Liking通常采用向量数据库(如Chroma, Weaviate)来实现长期记忆,使Agent能拥有“记忆力”。

2.2 工作原理与流程

Liking框架的工作流程可以概括为以下步骤,下图清晰地展示了这一交互循环:

flowchart TD A[用户/系统提出请求] --> B[框架组装当前对话上下文] B --> C[LLM进行思考与规划<br>(选择技能或直接回答)] C --> D{决策类型?} D -- 使用技能 --> E[执行对应的Skill函数/工具] E --> F[获取执行结果 Observation] F --> G[LLM整合结果生成本轮响应] D -- 直接回答 --> G G --> H[保存本轮完整记录<br>(User, Thought, Action, Observation, Response)] H --> I{任务是否完成?} I -- 否 --> B I -- 是 --> J[输出最终结果<br>结束对话]

这个循环的核心价值在于每一步都是可观测、可记录的。开发者可以随时查看“思考”内容,了解Agent的决策逻辑;也可以查看“行动”和“观察”,确认工具调用的准确性。这种透明性极大地提升了调试效率和系统可靠性。

3. 环境准备与前置条件

在开始编码之前,请确保你的开发环境满足以下要求。我们将以Python环境为例进行说明。

3.1 系统与语言要求

  • 操作系统:Linux (Ubuntu 20.04+), macOS, 或 Windows (WSL2推荐)。
  • Python版本:>= 3.8。建议使用3.9或3.10以获得最佳兼容性。
  • 包管理工具pippoetry。本文使用pip

3.2 获取项目代码

Liking是一个开源项目,你可以从代码托管平台克隆它。

# 克隆仓库 (请替换为实际仓库地址,此处为示例) git clone https://github.com/your-org/liking.git cd liking

3.3 安装核心依赖

项目根目录下通常会有requirements.txtpyproject.toml文件。

# 创建并激活虚拟环境 (强烈推荐) python -m venv venv source venv/bin/activate # Linux/macOS # venv\Scripts\activate # Windows # 安装依赖 pip install -r requirements.txt

如果项目使用poetry,则运行:

pip install poetry poetry install

3.4 配置LLM密钥

Liking本身不提供LLM,需要接入OpenAI、Anthropic或本地部署的Ollama等模型服务。你需要准备相应的API密钥。

创建一个名为.env的环境变量文件在项目根目录(注意:切勿将此文件提交到版本控制系统):

# .env 文件示例 OPENAI_API_KEY=sk-your-openai-api-key-here # 或者使用 Azure OpenAI AZURE_OPENAI_API_KEY=your-azure-key AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com/ # 或者使用 Anthropic Claude ANTHROPIC_API_KEY=your-claude-api-key

在代码中,框架会通过os.getenv读取这些配置。

4. 核心流程拆解:构建你的第一个智能体

现在,让我们动手构建一个简单的智能体。这个智能体的目标是扮演一个“技术文档助手”,能够回答关于Python编程的问题,并在必要时给出代码示例。

4.1 步骤一:定义Skill(技能)

Skill是Agent能力的基石。我们首先定义一个简单的“代码格式化”Skill。

在项目目录下创建skills/code_formatter.py

# skills/code_formatter.py import autopep8 from liking.skill import Skill, skill @skill class CodeFormatterSkill(Skill): """一个用于格式化Python代码的技能。""" name = "format_python_code" description = "格式化一段给定的Python代码,使其符合PEP8规范。" def execute(self, code: str) -> str: """ 执行代码格式化。 Args: code (str): 需要格式化的Python代码字符串。 Returns: str: 格式化后的代码字符串。 """ try: formatted_code = autopep8.fix_code(code) return formatted_code except Exception as e: return f"代码格式化失败,错误信息:{str(e)}"

关键点

  • 使用@skill装饰器注册。
  • 必须继承Skill基类(具体类名需根据框架实际定义调整)。
  • namedescription至关重要,LLM会根据这些描述来决定是否以及何时调用此技能。
  • execute方法是技能的核心逻辑。

4.2 步骤二:配置Agent与Memory

接下来,我们需要创建一个Agent,并为其配备记忆系统。这里我们使用简单的对话记忆和向量记忆。

创建agent_config.yaml

# configs/agent_config.yaml agent: name: "PythonDocAssistant" role: "你是一个专业的Python技术文档助手,擅长用简洁清晰的语言解释概念,并给出实用的代码示例。" model: "gpt-4-turbo-preview" # 或 "claude-3-sonnet-20240229", "gpt-3.5-turbo" temperature: 0.1 # 较低的温度使输出更稳定、更专注 memory: short_term: type: "conversation_buffer" # 存储最近的对话历史 max_turns: 10 long_term: type: "vector_store" # 用于存储和检索长期知识 store_type: "chroma" # 使用ChromaDB persist_directory: "./data/chroma_db" embedding_model: "text-embedding-3-small" skills: - "skills.code_formatter.CodeFormatterSkill" # 可以继续添加其他技能,如: # - "skills.web_search.WebSearchSkill" # - "skills.calculator.CalculatorSkill"

4.3 步骤三:初始化并运行Agent

现在,我们编写主程序来启动Agent并进行对话。

创建main.py

# main.py import asyncio import yaml from pathlib import Path from liking.agent import Agent from liking.memory import VectorMemory, ConversationBufferMemory def load_config(config_path: str): with open(config_path, 'r') as f: return yaml.safe_load(f) async def main(): # 1. 加载配置 config = load_config("configs/agent_config.yaml") # 2. 初始化记忆系统 short_memory = ConversationBufferMemory(max_turns=config['memory']['short_term']['max_turns']) long_memory = VectorMemory( store_type=config['memory']['long_term']['store_type'], persist_dir=config['memory']['long_term']['persist_directory'], embedding_model=config['memory']['long_term']['embedding_model'] ) # 3. 动态加载技能 skills = [] for skill_path in config['skills']: module_name, class_name = skill_path.rsplit('.', 1) module = __import__(module_name, fromlist=[class_name]) skill_class = getattr(module, class_name) skills.append(skill_class()) # 4. 创建Agent实例 agent = Agent( name=config['agent']['name'], role=config['agent']['role'], model=config['agent']['model'], temperature=config['agent']['temperature'], skills=skills, short_term_memory=short_memory, long_term_memory=long_memory ) # 5. 运行对话循环 print(f"Agent '{agent.name}' 已就绪。输入 'quit' 或 'exit' 结束对话。") while True: try: user_input = input("\nYou: ") if user_input.lower() in ['quit', 'exit', 'q']: print("对话结束。") break # 关键:调用Agent处理输入,获取完整回合 turn = await agent.process(user_input) # 打印Agent的响应 print(f"\n{agent.name}: {turn.response}") # (可选)打印详细的回合信息,用于调试 if input("查看详细回合信息?(y/N): ").lower() == 'y': print(f"\n[DEBUG] 思考过程: {turn.thought}") print(f"[DEBUG] 执行动作: {turn.action}") print(f"[DEBUG] 动作结果: {turn.observation}") except KeyboardInterrupt: print("\n对话被中断。") break except Exception as e: print(f"\n处理请求时出错: {e}") if __name__ == "__main__": asyncio.run(main())

5. 运行结果与效果验证

运行上述程序,你将进入一个交互式对话界面。让我们测试几个场景。

5.1 启动程序

python main.py

预期输出:

Agent 'PythonDocAssistant' 已就绪。输入 'quit' 或 'exit' 结束对话。 You:

5.2 测试基础问答

You: 请解释一下Python中的列表推导式。

预期Agent响应

PythonDocAssistant: 列表推导式是Python中一种简洁、高效地创建新列表的语法。其基本形式为 `[expression for item in iterable if condition]`。 例如,要生成一个包含0到9所有数字平方的列表,可以这样写: squares = [x**2 for x in range(10)] 这等价于: squares = [] for x in range(10): squares.append(x**2) 列表推导式更简洁,且通常执行速度更快。

5.3 测试Skill调用

You: 帮我格式化这段代码:`def hello():print("Hello, World!")`

预期Agent响应

PythonDocAssistant: 已调用代码格式化技能。格式化后的代码如下: ```python def hello(): print("Hello, World!")

现在它符合PEP 8规范了。

此时,如果你选择查看详细回合信息(`y`),可能会看到:

[DEBUG] 思考过程: 用户提供了一段格式不规范的Python代码。我拥有一个名为format_python_code的技能,描述是“格式化一段给定的Python代码,使其符合PEP8规范。”。这正好适用于当前请求。我将调用这个技能。 [DEBUG] 执行动作: CallSkill(name='format_python_code', args={'code': 'def hello():print("Hello, World!")'}) [DEBUG] 动作结果: def hello():\n print("Hello, World!")

**这就是`Liking`框架的核心价值体现**:整个决策和执行过程完全透明。 ### 5.4 测试上下文记忆

You: 我刚才问了你关于列表推导式的问题,你能再总结一下它的优点吗?

**预期Agent响应**:

PythonDocAssistant: 当然。根据我们之前的对话,列表推导式的主要优点有:

  1. 语法简洁:用一行代码替代多行的for循环,使代码更清晰易读。
  2. 执行高效:由于其实现方式,通常比等价的for循环执行速度更快。
  3. 功能强大:可以结合条件判断(if子句),方便地进行过滤。

例如,[x for x in range(10) if x % 2 == 0]可以快速生成一个偶数列表。

这表明Agent成功地从短期对话记忆中回忆起了之前的上下文。 ## 6. 常见问题与排查思路 在实际使用`Liking`或类似框架时,你可能会遇到以下问题。下表列出了常见现象、原因及解决方案。 | 问题现象 | 可能原因 | 排查方式 | 解决方案 | | :--- | :--- | :--- | :--- | | **Agent不调用Skill,总是直接回答** | 1. Skill的`name`或`description`描述不清晰,LLM无法匹配。<br>2. LLM的`temperature`参数过高,导致输出随机性大。<br>3. 提示词(Agent的`role`)中没有鼓励使用工具。 | 1. 检查回合的`thought`字段,看LLM是否识别了Skill但决定不用。<br>2. 降低`temperature`值(如设为0.1)。<br>3. 在Agent的`role`描述中明确加入“请充分利用你的技能来解决问题”。 | 优化Skill描述,使其更精准、更具操作性。调整模型参数。强化系统提示词。 | | **Skill执行出错或返回异常** | 1. Skill的`execute`方法内部代码有Bug。<br>2. 传入的参数类型或格式与预期不符。<br>3. 依赖的外部服务(如API)不可用。 | 1. 在Skill的`execute`方法中添加详细的日志和异常捕获。<br>2. 检查LLM生成的`action`中的参数是否正确。<br>3. 单独测试Skill函数。 | 完善Skill内部的错误处理。在Skill描述中明确参数格式要求。为外部调用添加重试和超时机制。 | | **上下文长度超限,导致历史被截断** | 对话轮次过多,或单次输入内容过长,超过了LLM模型的上下文窗口。 | 监控对话的Token消耗。检查记忆系统的`max_turns`设置。 | 1. 使用`ConversationSummaryMemory`替代`ConversationBufferMemory`,定期总结历史。<br>2. 在`long_term_memory`中存储重要信息,让Agent学会主动查询。<br>3. 优化提示词,让回复更简洁。 | | **向量记忆检索不到相关内容** | 1. 知识没有正确存入向量库。<br>2. 检索时使用的查询语句与存储的内容语义不匹配。<br>3. 相似度阈值设置过高。 | 1. 检查向量数据库的持久化目录是否有文件生成。<br>2. 手动测试向量检索接口,看返回结果。<br>3. 检查嵌入模型(embedding model)是否正常工作。 | 确保知识灌入流程正确。优化检索查询的表述(有时需要让LLM重写查询)。调整检索的相似度阈值和返回数量(top_k)。 | | **Agent陷入循环或无关对话** | 1. 系统提示词(`role`)约束力不够。<br>2. 记忆中存在误导性信息。<br>3. 任务本身模糊。 | 分析最近几轮的对话历史,看话题是如何偏离的。 | 1. 在系统提示词中设定更严格的边界和行为规范。<br>2. 实现一个“对话状态跟踪”机制,在偏离主题时进行纠正。<br>3. 设计更清晰、可分解的任务目标。 | ## 7. 最佳实践与工程建议 要将`Liking`框架用于生产环境或严肃项目,遵循以下最佳实践至关重要。 ### 7.1 Skill设计原则 * **单一职责**:每个Skill应只做一件事,并把它做好。避免创建功能臃肿的“超级Skill”。 * **描述精准**:`name`和`description`是LLM理解和使用Skill的唯一依据。描述应清晰说明功能、输入/输出格式和适用场景。 * **差描述**:“处理数据”。 * **好描述**:“根据给定的城市名称,查询该城市未来三天的天气预报,并以JSON格式返回温度、天气状况和日期。” * **健壮性**:Skill内部必须进行全面的参数验证和异常处理,返回结构化的错误信息,避免因单个Skill失败导致整个Agent崩溃。 * **无状态性**:尽可能将Skill设计为无状态的纯函数。状态应该由Agent的记忆系统管理。 ### 7.2 提示词工程 * **系统提示词(Role)是总纲**:它定义了Agent的身份、目标和行为边界。花时间精心打磨它。 * **分步骤思考(Chain of Thought)**:在提示词中鼓励LLM“一步一步思考”,并显式地考虑可用的Skill。这能提高决策的可靠性和可解释性。 * **提供示例(Few-Shot)**:在复杂的任务中,在系统提示词或初始上下文中提供一两个输入输出的示例,能显著提升Agent的表现。 ### 7.3 记忆与上下文管理 * **分层记忆策略**:结合使用短期缓冲记忆(用于保持对话流畅性)和长期向量记忆(用于存储和检索关键知识)。对于超长对话,考虑引入摘要记忆。 * **主动记忆**:不要依赖LLM自动记住一切。设计机制,让Agent主动将重要结论或用户偏好存储到长期记忆中。 * **定期清理**:为生产系统设计记忆的清理和归档策略,避免存储无限增长导致性能下降。 ### 7.4 监控与评估 * **全链路日志**:记录每一个回合的完整信息(User, Thought, Action, Observation, Response)。这是调试、分析和改进Agent的黄金数据。 * **定义评估指标**:根据你的应用场景,定义成功指标。例如:任务完成率、平均对话轮次、用户满意度评分、Skill调用准确率等。 * **A/B测试**:对不同的提示词、模型参数甚至Skill组合进行A/B测试,用数据驱动优化。 ### 7.5 安全与权限 * **Skill权限控制**:不是所有Skill都应对所有用户或所有场景开放。实现一个权限层,根据上下文决定是否启用某个Skill(例如,删除文件、调用支付接口等高风险操作)。 * **输入输出过滤**:对用户的输入和Agent的输出进行必要的安全检查,防止提示词注入、敏感信息泄露等攻击。 * **设置预算与限流**:监控API调用成本和频率,设置硬性限制,防止意外循环导致巨额费用。 “喜欢吗?我也喜欢~”这个项目,其有趣的名字背后,是一套对AI Agent开发范式的严肃思考。它通过“对话即任务”的清晰抽象,将黑盒的自动化过程,转变为白盒的、可协作的、可调试的交互流程。这对于需要将AI能力稳定、可靠地集成到复杂业务系统中的开发者来说,价值巨大。 本文带你从核心理念走到实际部署,涵盖了环境搭建、Skill开发、Agent配置、运行调试和最佳实践的全链路。真正的价值不在于运行通一个Demo,而在于理解这种“可控Agent”的设计思想,并将其应用于解决你自己的实际问题——无论是内部效率工具、智能客服原型,还是复杂决策支持系统。 下一步,你可以尝试: 1. **集成更多技能**:为你的Agent添加网络搜索、数据库查询、图表生成等能力。 2. **探索Web界面**:基于`Liking`的核心引擎,构建一个图形化的聊天界面,提升用户体验。 3. **连接真实数据源**:将Agent与你公司的内部知识库、CRM或ERP系统对接,打造真正的“企业数字员工”。 4. **研究多Agent协作**:如何让多个各司其职的`Liking` Agent相互对话、协作完成更宏大的任务? 这个领域正在快速演进,但核心的命题不变:如何让强大的人工智能,成为人类可靠、透明、高效的合作伙伴。`Liking`框架提供了一个极具潜力的解题思路。建议收藏本文,在实践过程中随时参考。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询