基于Elixir与Jido框架构建可深度定制的个人AI智能体系统

基于Elixir与Jido框架构建可深度定制的个人AI智能体系统 1. 项目概述一个用Elixir构建的、可深度定制的个人AI智能体如果你对AI智能体Agent感兴趣并且希望有一个完全由自己掌控、能深度融入你的工作流、甚至能记住你的习惯和偏好的“数字伙伴”那么Goodwizard值得你花时间研究。它不是一个简单的聊天机器人包装而是一个基于Elixir语言和Jido框架构建的、功能完整的个人AI操作系统。它的核心魅力在于“可塑性”——从底层记忆结构到外在性格你都可以通过编辑几个Markdown文件来定义。想象一下你不仅是在“使用”一个AI更是在“塑造”一个专属于你的、不断学习和成长的数字实体。这个项目由agoodway团队开源其设计哲学非常清晰将AI的能力从封闭的聊天窗口解放出来变成一个可以通过文件、命令行、定时任务、甚至心跳文件来触发的后台服务。这意味着你可以通过写一个脚本、修改一个文件或者设置一个定时任务来让AI帮你处理邮件摘要、检查项目进度、自动整理知识库而无需每次都打开一个聊天界面。它把AI变成了一个像Cron或Systemd一样的基础设施组件。2. 核心架构与设计哲学解析2.1 为什么选择Elixir和JidoGoodwizard的技术栈选择非常有意思。Elixir是一门构建在Erlang虚拟机BEAM上的函数式语言以其高并发、容错性和“任其崩溃”的哲学闻名。Jido则是一个专门为构建AI智能体而设计的Elixir框架。这两者的结合为Goodwizard带来了几个先天优势高并发与隔离性Elixir的轻量级进程Process是构建并发系统的绝佳模型。Goodwizard利用这一点可以轻松地同时运行数十个独立的“子智能体”Sub-agent每个都处理不同的任务如定时任务、心跳触发彼此之间完全隔离。一个任务崩溃不会影响主会话或其他任务这比用Python或Node.js写的单线程Agent要稳健得多。热代码升级与状态管理BEAM虚拟机支持热更新理论上Goodwizard可以在不停止服务的情况下更新其技能或逻辑。虽然当前版本未直接暴露此功能但底层框架为未来的动态扩展提供了可能。“工具调用”作为一等公民Jido框架原生将工具调用Tool Calling和ReAct推理-行动循环作为核心抽象。这使得Goodwizard能非常自然地让AI决定何时、如何使用文件系统、浏览器、Shell等工具而不是写死一堆if-else逻辑。注意选择Elixir也意味着一定的学习门槛。如果你不熟悉函数式编程或OTPElixir的并发框架初期配置和调试可能会有些挑战。但一旦上手其架构的清晰度和可靠性会带来巨大回报。2.2 模块化的工作空间智能体的“数字大脑”Goodwizard没有将智能体的“人格”和“知识”硬编码在代码里而是将其外化到一个文件系统工作空间默认是priv/workspace/。这是它最精妙的设计之一。你可以把这个工作空间想象成智能体的“大脑皮层”由几个关键文件构成IDENTITY.md定义智能体“是谁”。包括名字、角色如“高效的个人助理”、“创意伙伴”、沟通语气正式、随意、鼓励式。这是塑造第一印象的关键。SOUL.md定义智能体的“价值观和行为准则”。比如“始终优先考虑用户的隐私”、“在提供建议时解释推理过程”、“承认知识边界”。这相当于它的道德罗盘和操作原则。USER.md智能体所了解的“关于你的一切”。你的职业、常用工具、项目目标、个人偏好比如“我讨厌冗长的邮件”、“我喜欢用Markdown做笔记”。这是它提供个性化服务的基础。MEMORY.md动态更新的语义记忆。这不是聊天记录而是智能体从中提炼出的关于你的持久性认知比如“用户通常在周二下午进行代码评审”、“用户对Python的异步编程比较熟悉”。这个文件会随着对话被智能体主动更新。启动时一个叫Preamble.Hydrator的模块会将这些文件连同当前可用的工具列表、知识库模式等运行时状态组合成一个完整的“系统提示词”System Prompt。这意味着你只需编辑这些Markdown文件就能从根本上改变智能体的行为和知识背景无需改动一行代码。2.3 三层记忆系统从短期对话到长期学习一个只会聊天的AI是“金鱼”而Goodwizard试图构建的是“大象”般的记忆。它的记忆系统分为三层模拟了人类不同的记忆类型语义记忆Semantic如上文所述存储在MEMORY.md中。是智能体对你形成的抽象化、概括性的认知。情景记忆Episodic存储在memory/episodic/目录下每个文件都是一次不可变的“经历”记录。例如“2024-05-10成功帮用户使用grep命令在项目日志中找到了错误。”、“2024-05-11用户拒绝了关于使用新笔记工具的建议。”。这些是事实性的历史档案供智能体在需要参考过去具体事件时检索。程序性记忆Procedural存储在memory/procedural/目录下是智能体“学会”的工作流程或模式。例如“如何为用户生成日报”可能是一个程序性记忆。它会记录该流程被成功执行的次数、最后一次使用时间并有一个“置信度”分数。不常用的流程会随时间“衰减”最终可能被归档。这是实现智能体自主学习和技能优化的关键机制。当一次对话会话变得很长时Goodwizard会启动一个“记忆巩固”过程自动从对话记录中提取新的情景记忆和程序性记忆并更新语义记忆。这模拟了人类睡眠中记忆巩固的过程使得智能体能够真正从交互中学习。3. 核心功能与实操指南3.1 知识库结构化的个人数据枢纽Goodwizard内置了一个基于文件的知识库支持“人物”、“地点”、“事件”、“笔记”、“任务”、“公司”等实体类型。它的运作方式很优雅模式驱动每种实体类型都有一个JSON Schema定义在代码中。这确保了数据的结构化和有效性。文件存储每个实体都保存为一个Markdown文件包含YAML前端元数据存储结构化字段和正文内容。例如一个“人物”实体文件可能包含name、role、contact等字段。自动生成工具启动时系统会根据这些Schema为每种实体类型自动生成对应的工具函数如create_person、search_notes、update_task。这意味着你可以直接对智能体说“把‘张三’加到知识库里他是某公司的后端工程师邮箱是zhangsanexample.com”智能体就会调用相应的工具来创建这个实体。实体关联实体之间可以通过“type/uuid”格式的字符串相互引用。例如一个“任务”实体可以关联到多个“人物”实体负责人。实操心得初期建议从“笔记”和“任务”类型开始用起。你可以让智能体帮你记录会议纪要创建一个“笔记”实体或者管理待办清单创建“任务”实体。知识库的力量在于关联查询例如你可以问“上个月所有和‘项目A’相关的会议笔记有哪些”3.2 技能系统可插拔的能力扩展技能Skills是Goodwizard扩展AI能力的主要方式。它采用了一种聪明的“两层加载”设计技能摘要每个技能目录如skills/weather/下都有一个SKILL.md文件。系统启动时会提取所有技能的摘要部分并将其嵌入到每次对话的系统提示词中。这样智能体就知道有哪些技能可用以及它们的简要用途。按需加载只有当智能体决定要使用某个技能时比如用户问“今天天气怎么样”它才会通过activate_skill工具去加载该技能SKILL.md文件的完整内容通常包含详细的API调用指令、参数说明、示例等。这种设计完美平衡了上下文长度限制和功能丰富性。项目自带了一个weather技能它整合了wttr.in和Open-Meteo两个天气数据源。你可以参考它来创建自己的技能比如send_email、query_database或control_smart_home。创建自定义技能步骤在priv/workspace/skills/下新建一个目录例如my_skill。在该目录下创建SKILL.md文件。文件结构通常包括# Summary一两句话描述技能用途这部分会被摘要。# Full Instructions详细的调用说明、所需参数、API端点、示例请求/响应。# Examples用户可能如何触发此技能的对话示例。重启Goodwizard你的新技能摘要就会被自动识别。3.3 心跳与调度让智能体自主运行这是Goodwizard从“交互工具”蜕变为“自主系统”的核心功能。心跳Heartbeat 这是一个由GenServerElixir的通用服务器实现的定时轮询机制。它每隔N分钟可配置检查一次HEARTBEAT.md文件的修改时间。如果发现文件被改动它就会读取文件内容将其作为提示词发送给智能体处理并将回复保存起来。这打开了无限的自动化可能性。你可以用任何能写文件的方式触发AI一个cron作业echo “生成昨日销售报告摘要” HEARTBEAT.md一个Git钩子在代码推送后让CI/CD流水线写入“分析本次提交的变更”。一个监控脚本当服务器磁盘使用率超过90%时写入“警告磁盘空间不足请分析并给出清理建议”。调度Scheduling Goodwizard支持标准的cron表达式来定义周期性任务也支持daily、hourly这样的别名。每个定时任务触发时都会在一个完全隔离的子智能体中运行确保不会干扰你当前可能正在进行的交互会话。配置一个每日早安简报的示例 在config.toml的[scheduled_tasks]部分或通过对话添加[[scheduled_tasks]] schedule 0 9 * * * # 每天上午9点 prompt 现在是早上9点。请检查我的知识库中所有状态为‘进行中’的任务总结今日待办事项并查看天气。以简洁的列表格式回复。 channel cli # 或 “telegram” chat_id morning_brief3.4 工具集智能体的“手脚”Goodwizard为智能体装备了一套强大的工具使其能与现实世界交互工具类别能力说明安全考量文件系统在工作空间内读写、编辑、搜索文件。默认限制在工作空间内防止误操作系统文件。Shell执行运行命令行指令。通过deny_patterns配置正则表达式黑名单可屏蔽rm -rf /、dd等危险命令。超时机制防止死循环。浏览器自动化使用Vibium或Playwright驱动浏览器进行点击、输入、截图、抓取内容。可在无头模式运行适合服务器环境。知识库对内置实体类型的增删改查。由JSON Schema校验保证数据一致性。记忆对三层记忆系统的读写操作。智能体可以自主决定记住或回忆什么。消息向指定的“房间”如CLI会话、Telegram聊天发送消息。用于任务完成通知或主动汇报。子智能体派生出独立的智能体来处理特定子任务。受max_concurrent_agents限制避免资源耗尽。调度创建和管理定时或一次性任务。任务持久化到磁盘重启后不丢失。关于Shell工具的安全实践 在生产环境或处理敏感操作时务必仔细审查和配置config.toml中的[tools.exec]部分的deny_patterns。默认列表已经包含了一些危险模式但你应根据自己的需要增补。例如如果你完全不想让智能体接触数据库可以加入.*(drop|alter)\\stable.*之类的规则。4. 从零开始部署与深度配置4.1 环境准备与初始化假设你已经在系统上安装了Elixir 1.17和Just命令运行器。# 1. 克隆项目 git clone https://github.com/agoodway/goodwizard.git cd goodwizard # 2. 获取依赖 mix deps.get # 3. 运行初始化设置 mix goodwizard.setupmix goodwizard.setup这个命令是关键它会创建整个工作空间目录结构、默认的配置文件config.toml以及那些核心的身份文件IDENTITY.md,SOUL.md等的模板。你的“塑造智能体”之旅就从编辑这些文件开始。4.2 核心身份文件定制指南不要跳过这一步这是赋予Goodwizard灵魂的过程。编辑IDENTITY.mdName Role给它起个名字定义核心角色。例如“CodeWizard你的专属软件开发助手”。Tone Style定义沟通风格。是像导师一样严谨还是像朋友一样随意例如“使用专业但友好的语气。在解释复杂概念时使用比喻。避免使用‘呃’、‘嘛’等不确定的词语。”Capabilities简要说明它能做什么工具概览让它在自我介绍时更准确。编辑SOUL.md核心原则列出最高行为准则。例如“1. 用户隐私和安全至高无上。2. 在采取任何具有潜在影响的行动如运行命令、修改文件前必须明确征得用户同意。3. 如果对某件事不确定应坦诚说明而非猜测。”推理框架指导它如何思考。例如“遵循ReAct模式先思考Reason再行动Act。在思考步骤中简要分析目标、可用工具和潜在风险。”编辑USER.md关于我你的职业、技术栈、常用工具编辑器、编程语言、项目管理软件。工作流偏好你喜欢的交互方式。例如“我喜欢你提供选项让我选择而不是直接执行。报告请尽量用Markdown列表或表格。对于代码优先提供片段而非完整文件。”当前项目你正在进行的重点工作方便它提供上下文相关的帮助。4.3 通道配置CLI与TelegramCLI通道默认启用。运行mix goodwizard.cli会进入一个交互式REPL。这是开发和调试的主要界面。会话历史会保存在sessions/目录下方便回溯。Telegram通道配置详解按项目文档创建Bot并获取Token填入.env文件。在config.toml中启用[channels.telegram] enabled true allow_from [123456789] # 你的Telegram User ID从userinfobot获取高级功能角色覆盖。你可以让Telegram上的Bot和CLI里的智能体表现出略微不同的性格。这在config.toml中通过character_overrides实现[channels.telegram.character_overrides] preamble 你现在在Telegram上与我对话。请使你的回复更加简洁、活泼可以适当使用表情符号。在提供链接时请使用Markdown内联链接格式。这个preamble会附加到Telegram通道的系统提示词中从而覆盖或调整基础身份设定。4.4 模型与性能调优config.toml中的[agent]部分控制着核心LLM的行为model默认使用anthropic:claude-sonnet-4-5。你也可以尝试anthropic:claude-haiku-3更快、更便宜或其他支持的模型。max_tokens控制单次回复的最大长度。对于复杂的分析任务可以调高如16384。对于心跳触发的简短任务可以调低以节省成本。temperature创造性。0.7是一个不错的平衡点。如果你需要更确定、可重复的输出如生成数据可以降到0.2如果需要更多创意可以升到0.9。max_tool_iterationsReAct循环的最大次数。防止智能体陷入“思考-行动”的死循环。对于简单任务10可能就够了对于需要多步骤探索的复杂任务可以设为20或更高。memory_window保留在对话上下文中的最近消息数量。这直接影响API调用的token消耗。如果你的对话很长且不想丢失早期上下文可以调大但需注意成本。5. 实战场景与进阶技巧5.1 场景一个人知识管理与日报生成目标让Goodwizard自动整理你一天中产生的零散信息并生成结构化日报。实现步骤知识库录入养成习惯将任何想法、会议记录、待办事项通过对话让Goodwizard存入知识库。例如“将‘下午与团队讨论项目B的API设计决定采用RESTful风格’保存为一条笔记关联到‘项目B’和‘团队会议’标签。”创建日报技能编写一个daily_report技能。在SKILL.md中详细指导智能体如何查询知识库检索过去24小时内创建或修改的所有“笔记”和“任务”实体按项目或标签分类总结进展和待办项。设置定时心跳创建一个cron任务或使用Just命令在每天下班时间如下午6点向HEARTBEAT.md写入“现在执行每日报告技能总结我今天的工作进展和明天的待办事项。”输出智能体执行技能生成Markdown格式的日报并可以通过Telegram Bot直接发送给你或者保存到工作空间的一个指定文件中。5.2 场景二自动化网站监控与警报目标监控某个网页内容的变化如产品价格、职位发布、博客更新并在变化时通知你。实现步骤创建监控技能编写一个monitor_website技能。利用浏览器工具访问指定URL提取关键内容如价格数字、文章标题列表计算哈希值或与上次抓取的内容进行差异对比。利用程序性记忆让技能将每次抓取的结果或哈希作为一个“情景记忆”保存。下次执行时先读取上次的记忆进行对比。设置高频心跳将heartbeat.interval_minutes设置为15或30分钟。触发逻辑写一个简单的Shell脚本定期比如每小时运行。脚本首先调用monitor_website技能通过写入HEARTBEAT.md如果技能检测到变化就在脚本中通过curl命令调用Telegram Bot API或其他通知服务直接向你发送警报。Goodwizard负责复杂的抓取和对比逻辑外部脚本负责轻量的调度和通知。5.3 场景三作为开发助手进行代码库交互目标在CLI中让Goodwizard帮你理解代码、查找bug、甚至生成小段代码。配置要点扩大文件系统权限在config.toml中将[tools]部分的restrict_to_workspace设置为false请务必谨慎并配合严格的Shell命令黑名单。或者更安全的方式是将你的代码库符号链接symlink到工作空间内。增强USER.md在USER.md中详细说明你的项目技术栈、目录结构、代码规范。使用方式代码解释“请分析lib/goodwizard/preamble.ex文件中的hydrate/1函数解释它的主要逻辑。”Bug查找“我在运行mix test test/goodwizard_test.exs:25时遇到一个错误错误信息是…。请结合相关代码帮我分析可能的原因。”代码生成“在lib/my_app/目录下按照现有模式创建一个新的上下文模块Blog包含Posts和Comments两个模式。”重要心得让AI直接操作生产代码库存在风险。最佳实践是① 始终在独立的开发分支或副本上进行。② 要求智能体在修改任何文件前必须提供完整的差异预览diff并等待你的明确确认。③ 将这条规则写入SOUL.md的核心原则中。6. 故障排除与性能优化6.1 常见问题速查表问题现象可能原因解决方案启动时mix deps.get失败网络问题或Hex镜像不可用运行mix hex.repo add hex https://mirrors.cloud.tencent.com/hex切换国内镜像或检查代理设置。mix goodwizard.setup不创建文件依赖未正确安装或路径权限问题确保mix deps.get成功。检查当前用户对项目目录有写权限。CLI启动后无响应或立即退出Elixir版本不匹配或环境变量缺失确认Elixir版本≥1.17。检查.env文件是否存在且包含有效的ANTHROPIC_API_KEY。运行echo $ANTHROPIC_API_KEY验证环境变量已加载。智能体不调用工具只是空想系统提示词可能被覆盖或工具注册失败检查priv/workspace/下的身份文件是否格式正确。查看启动日志确认所有工具特别是知识库工具已成功加载。尝试在SOUL.md中强调“积极使用工具解决问题”。Telegram Bot不回复消息Token错误、配置未启用或网络问题1. 确认.env中的TELEGRAM_BOT_TOKEN正确。2. 确认config.toml中[channels.telegram]的enabled true。3. 检查服务器网络是否能访问Telegram API。4. 查看应用日志_build/dev/log/erlang.log.*。心跳文件被读取后内容未清空这是设计如此心跳机制基于文件修改时间。只有内容变化才会触发。如果想再次触发需要修改文件内容如追加一个空格再保存。执行Shell命令被拒绝命令匹配了deny_patterns黑名单检查config.toml中[tools.exec]的deny_patterns。对于需要运行的安全命令可以临时调整黑名单规则或考虑将其封装成一个安全的自定义脚本供智能体调用。浏览器工具无法启动缺少Chromium或Playwright依赖如果使用playwright适配器需运行mix playwright.install。确保系统已安装必要的库如libnss3,libxss1等。在Docker中运行时需要使用包含浏览器依赖的镜像。6.2 性能与资源管理控制并发量scheduled_tasks.max_concurrent_agents默认50限制了同时运行的子智能体数量。如果你的定时任务密集或处理很慢可能会排队。监控日志如果发现任务被跳过可以考虑适当增加此值但需权衡服务器资源。管理会话内存agent.memory_window控制保留的对话轮数。过大的值会导致每次API调用携带大量历史增加成本和延迟。对于长期运行的Telegram会话可以设置一个合理的值如30-50并依赖“记忆巩固”机制将重要信息转移到长期记忆中。浏览器工具超时browser.timeout默认30秒控制单个浏览器操作的等待时间。对于加载缓慢的页面可能需要调高。tools.exec.timeout默认60秒控制Shell命令超时。日志与监控Goodwizard使用标准的Elixir Logger。可以通过修改config/runtime.exs来调整日志级别如设置为:info减少调试噪音。关注_build/dev/log/下的日志文件是排查问题的第一手资料。6.3 自定义与扩展思路当你熟悉基础功能后可以从以下方向深度定制开发新工具Jido框架使得添加新工具相对简单。你可以参照lib/goodwizard/tools/下的现有模块创建一个新的工具模块实现Goodwizard.Tools行为Behaviour并将其注册到工具列表中。例如添加一个连接内部数据库查询的工具或调用一个内部API。集成外部系统利用“心跳”和“Shell工具”Goodwizard可以成为各种系统的胶水层。例如让CI/CD流水线在部署失败时写入心跳文件Goodwizard分析日志并给出修复建议或者让智能体定期查询健康检查端点并在异常时通知你。优化记忆策略默认的记忆巩固逻辑可能不适合所有场景。你可以深入研究lib/goodwizard/memory/consolidation.ex模块调整从对话中提取情景和程序性记忆的规则使其更符合你的需求。前端界面虽然提供了CLI和Telegram但你完全可以基于其API通过心跳文件或直接调用内部模块构建一个Web前端提供更丰富的交互体验。Goodwizard不是一个开箱即用的消费级产品而是一个为开发者和技术爱好者准备的“智能体构建套件”。它的力量来自于其高度的模块化和可编程性。投入时间配置它、教导它、将它融入你的流程你最终收获的将不仅仅是一个工具而是一个能够随着你一起进化的数字化助手。