在AI技术日新月异的今天,你是否也陷入了这样的困境:刚花时间调教好一个AI助手,熟悉了它的“脾气”,结果新模型发布,旧版本被淘汰,一切又得从头再来?或者,你精心设计的提示词(Prompt)在ChatGPT上效果拔群,换到Claude或Gemini上却水土不服,需要反复调整?这种对特定AI模型的依赖,不仅耗费精力,也让我们的数字工作流变得脆弱。
本文将为你彻底解决这个问题。我们不依赖任何单一的、会过时的AI模型,而是构建一套属于你自己的、可移植的“AI个人档案”。这套档案的核心是你的思维习惯、知识结构和交互偏好,通过标准化的数据格式和工具链进行封装。无论底层是ChatGPT、Claude、Gemini,还是未来任何新模型,你的“档案”都能快速适配,让你始终拥有一个高度个性化、稳定高效的AI伙伴。下面,我将从概念、设计到实战,手把手带你构建这套“一劳永逸”的AI个人工作流。
1. 为什么需要AI个人档案:超越模型依赖
1.1 当前AI使用的核心痛点
我们与AI的交互,本质上是在做两件事:输入指令(Prompt)和处理输出。目前的痛点在于:
- 模型锁定:为某个模型(如GPT-4)优化的Prompt,在其他模型(如Claude 3)上效果可能大打折扣。
- 上下文丢失:有价值的对话历史、你纠正AI的反馈、它学习到的你的偏好,都封闭在特定平台的某次会话中,难以沉淀和复用。
- 工具链割裂:用于处理AI输出的脚本、用于优化Prompt的模板、用于保存知识片段的系统,往往是零散的,无法形成一个自动化的工作流。
1.2 AI个人档案的定义与价值
AI个人档案是一套独立于任何AI模型的、结构化的个人数字资产。它包含:
- 核心身份与偏好:你希望AI扮演的角色(如“资深技术顾问”、“严谨的文案审校”)、你的专业领域、你喜欢的回复风格(简洁/详尽、正式/随意)。
- 知识库与上下文:你经常引用的个人项目信息、专业术语解释、常用的代码片段、历史对话中的精华总结。
- Prompt模板库:针对不同任务(代码评审、文章大纲、数据分析)优化过的、可参数化的Prompt模板。
- 后处理脚本与工具:用于解析、格式化、保存AI输出的自动化脚本。
它的核心价值是将“你”从具体的AI服务中解耦出来。模型会更新、服务会变迁,但你的思维模式和知识体系是持续积累的。档案就是这套体系的数字化载体。
1.3 应用场景
- 开发者:保存常用的技术栈上下文、API使用范例、项目架构描述,让AI在分析代码时更有针对性。
- 内容创作者:存储写作风格指南、品牌调性要求、内容模板,确保AI生成的内容保持一致性。
- 研究者/学生:积累文献阅读笔记、研究问题清单、论文写作框架,让AI协助思考时背景更充分。
- 多模型使用者:在ChatGPT、Claude、DeepSeek等模型间无缝切换,用同一套档案获得相近质量的输出。
2. 环境准备与核心工具选型
构建个人档案不依赖特定编程语言,但为了可移植和自动化,我们选择以文本文件(Markdown/JSON/YAML)为基础,以Python脚本作为粘合剂和自动化工具。这是最通用、最易维护的方案。
2.1 基础环境
- 操作系统:Windows 10/11, macOS, 或 Linux (Ubuntu 20.04+)。本文示例在 macOS/Linux 环境下编写,Windows 用户建议使用 WSL2 或 Git Bash 以获得一致的命令行体验。
- Python:版本 3.8 或以上。这是与各大AI平台API交互的主流语言版本。
- 包管理工具:
pip(Python自带)。
2.2 推荐工具与库
我们将使用以下工具构建一个轻量但完整的系统:
- 文本编辑器/IDE:VS Code(推荐),配合 Markdown、YAML、JSON 插件。
- 版本控制:Git。用于管理档案的变更历史,强烈推荐。
- 核心Python库:
openai:官方库,用于调用 OpenAI (ChatGPT) API。anthropic:官方库,用于调用 Claude API。google-generativeai:官方库,用于调用 Gemini API。python-dotenv:管理API密钥等环境变量。pyyaml或ruamel.yaml:读写YAML格式的配置文件。rich:在终端输出漂亮的彩色文本和表格,提升脚本使用体验。
2.3 项目初始化
在你的工作目录下,创建如下结构的项目文件夹:
ai_personal_profile/ ├── .env # 存储API密钥(切勿提交至Git) ├── .gitignore # Git忽略文件 ├── profile/ # 个人档案核心目录 │ ├── identity.yaml # 身份与偏好 │ ├── knowledge_base.md # 知识库 │ └── prompts/ # Prompt模板目录 │ ├── coding.yaml │ ├── writing.yaml │ └── analysis.yaml ├── scripts/ # 工具脚本目录 │ ├── __init__.py │ ├── profile_loader.py # 档案加载器 │ ├── chat_cli.py # 命令行聊天客户端 │ └── output_parser.py # 输出解析器 ├── outputs/ # AI输出保存目录 │ └── .gitkeep └── requirements.txt # Python依赖列表首先,创建并激活Python虚拟环境(可选但推荐):
# 进入项目目录 cd ai_personal_profile # 创建虚拟环境(Python 3.8+) python3 -m venv venv # 激活虚拟环境 # macOS/Linux: source venv/bin/activate # Windows (cmd): # venv\Scripts\activate.bat # Windows (PowerShell): # .\venv\Scripts\Activate.ps1然后,创建requirements.txt文件并安装依赖:
openai>=1.0.0 anthropic>=0.25.0 google-generativeai>=0.3.0 python-dotenv>=1.0.0 pyyaml>=6.0 rich>=13.0.0安装命令:
pip install -r requirements.txt创建.gitignore文件,确保不提交敏感信息:
# Python venv/ __pycache__/ *.pyc # Environment variables .env # AI outputs (optional, you might want to track some) outputs/* !outputs/.gitkeep # IDE .vscode/ .idea/3. 构建你的核心AI个人档案
档案的核心是数据。我们使用人类和机器都易读的格式来定义。
3.1 身份与偏好 (profile/identity.yaml)
这个文件定义了AI与你互动时的“基础人格”。它不绑定任何模型,而是描述你的需求。
# profile/identity.yaml user: name: "你的名字或昵称" core_identity: | 你是一名专注于后端开发与系统架构的资深工程师,拥有超过8年的Java和Go语言经验。 你对分布式系统、高并发处理和云原生技术有深入的理解和实践。 你的沟通风格直接、务实,偏好用代码和架构图辅助表达。 interaction_preferences: tone: "professional" # 可选: professional, casual, academic, friendly detail_level: "balanced" # 可选: concise, balanced, exhaustive language: "zh-CN" # 回复语言偏好 response_format: # 你希望AI如何组织回复 - "先给出核心结论或答案" - "然后分点阐述理由或步骤" - "最后提供可选的补充信息或注意事项" avoid: - "过度使用比喻和修辞" - "在没有数据支撑时使用‘绝对’、‘最好’等词汇" # 可以定义多个角色,在不同场景下切换 roles: code_reviewer: name: "严格代码审查员" instruction: | 请以Google代码风格指南和行业最佳实践为标准,严格审查以下代码。 重点指出:1. 潜在bug;2. 性能瓶颈;3. 可读性问题;4. 安全性隐患。 对每个问题,请给出具体的代码修改建议。 learning_partner: name: "学习伙伴" instruction: | 当我向你请教一个新概念时,请用“费曼学习法”的风格回应。 先用一个类比让我理解核心思想,然后给出一个最简单的代码示例, 最后提出两个关键问题,检验我是否真正理解。3.2 知识库 (profile/knowledge_base.md)
这是一个动态增长的Markdown文件,记录你独有的、需要AI在对话中知晓的背景信息。
# 我的知识库 ## 个人项目 ### 项目A: 分布式任务调度平台 (Project-Scheduler) - **技术栈**: Go, PostgreSQL, Redis, Docker, Kubernetes - **核心架构**: 采用Master-Worker模式,Master负责任务分发与状态管理,Worker通过gRPC接收任务。 - **关键设计决策**: 1. 使用PostgreSQL的SKIP LOCKED处理任务抢占,避免数据库悲观锁性能瓶颈。 2. Worker通过心跳机制向Master注册,Master采用一致性哈希算法分配任务,提高容错性。 - **相关代码片段**: ```go // 任务抢占SQL UPDATE tasks SET status = 'running', worker_id = $1 WHERE id IN ( SELECT id FROM tasks WHERE status = 'pending' ORDER BY priority DESC, created_at ASC FOR UPDATE SKIP LOCKED LIMIT 1 ) RETURNING id, payload;专业术语与缩写
- SLA: 在我的上下文中,通常指系统可用性达到99.95%,平均响应时间<200ms。
- “双写”: 特指我们项目中,为了平滑迁移,同时向新旧两套数据库写入数据的过渡方案。
常用参考
- 内部API端点:
https://api.internal.com/v1/users/{id}(认证方式: Bearer Token) - 团队代码规范链接:
https://wiki.company.com/code-style-guide - 常用工具命令:
kubectl logs -f deployment/project-scheduler-master --tail=50
### 3.3 Prompt模板库 (`profile/prompts/`) 将常用的、验证过的Prompt抽象成可复用的模板。使用YAML便于参数化。 ```yaml # profile/prompts/coding.yaml templates: explain_code: name: "解释代码块" description: "请求AI解释一段代码的功能、逻辑和关键点。" system_prompt: "你是一个耐心的编程导师。" user_prompt_template: | 请详细解释以下{language}代码。请按以下结构回答: 1. **整体功能**:用一句话总结这段代码做了什么。 2. **逐行/逐段解析**:解释关键行或逻辑块的作用。 3. **核心算法/技巧**:指出其中使用的关键算法、设计模式或编程技巧。 4. **潜在改进**:基于最佳实践,指出可以优化的地方(如果有)。 代码: ```{language} {code} ``` variables: ["language", "code"] # 声明模板变量 generate_boilerplate: name: "生成样板代码" description: "根据要求生成特定框架或功能的初始代码。" system_prompt: "你是一个经验丰富的软件开发助手。" user_prompt_template: | 请使用{framework},创建一个{component_type},要求如下: - 功能:{functionality_description} - 必须包含:{required_elements} - 代码风格:{code_style} 请只输出最终的代码文件内容,并在开头用注释简要说明。 variables: ["framework", "component_type", "functionality_description", "required_elements", "code_style"] # profile/prompts/writing.yaml templates: outline_from_theme: name: "根据主题生成文章大纲" description: "输入一个主题,生成逻辑清晰的文章大纲。" system_prompt: "你是一个专业的编辑和内容策略师。" user_prompt_template: | 请为主题“{theme}”生成一份详细的文章大纲。 目标读者是{target_audience},文章类型是{article_type}。 大纲需要包含: 1. 一个吸引人的标题(提供3个选项)。 2. 引言部分的核心论点。 3. 至少3个主要章节,每个章节下包含2-3个子论点。 4. 结论部分的核心总结。 5. 建议的Call-to-Action(行动号召)。 variables: ["theme", "target_audience", "article_type"]4. 实战:开发档案加载与AI交互脚本
有了结构化的档案,我们需要工具来使用它。我们将编写一个Python模块来加载档案,并创建一个简单的命令行客户端,可以选择不同的AI模型进行对话。
4.1 档案加载器 (scripts/profile_loader.py)
这个模块负责读取和解析我们的YAML和Markdown档案。
# scripts/profile_loader.py import os import yaml from pathlib import Path from typing import Dict, Any, Optional class ProfileLoader: def __init__(self, profile_dir: str = "./profile"): self.profile_dir = Path(profile_dir) self.identity = None self.knowledge_base = "" self.prompts = {} def load_all(self): """加载所有档案组件""" self.load_identity() self.load_knowledge_base() self.load_prompts() return self def load_identity(self) -> Dict[str, Any]: """加载身份配置文件""" identity_path = self.profile_dir / "identity.yaml" with open(identity_path, 'r', encoding='utf-8') as f: self.identity = yaml.safe_load(f) print(f"[加载] 身份档案: {self.identity.get('user', {}).get('name', 'N/A')}") return self.identity def load_knowledge_base(self) -> str: """加载知识库Markdown文件""" kb_path = self.profile_dir / "knowledge_base.md" if kb_path.exists(): with open(kb_path, 'r', encoding='utf-8') as f: self.knowledge_base = f.read() print(f"[加载] 知识库,长度: {len(self.knowledge_base)} 字符") else: print(f"[警告] 知识库文件未找到: {kb_path}") self.knowledge_base = "" return self.knowledge_base def load_prompts(self) -> Dict[str, Any]: """加载所有Prompt模板""" prompts_dir = self.profile_dir / "prompts" self.prompts = {} if prompts_dir.exists() and prompts_dir.is_dir(): for yaml_file in prompts_dir.glob("*.yaml"): with open(yaml_file, 'r', encoding='utf-8') as f: category = yaml_file.stem # 例如 'coding' self.prompts[category] = yaml.safe_load(f) print(f"[加载] Prompt类别: {category}") else: print(f"[警告] Prompt目录未找到: {prompts_dir}") return self.prompts def get_system_prompt(self, role: str = "default") -> str: """根据身份和角色构建系统提示词""" if not self.identity: self.load_identity() base_identity = self.identity.get("user", {}).get("core_identity", "") prefs = self.identity.get("interaction_preferences", {}) format_guide = "\n".join(prefs.get("response_format", [])) system_message = f""" 你正在与{self.identity.get('user', {}).get('name')}对话。 他的核心身份是:{base_identity} 请遵循以下交互偏好: - 语气:{prefs.get('tone', 'professional')} - 详细程度:{prefs.get('detail_level', 'balanced')} - 语言:{prefs.get('language', 'zh-CN')} - 回复结构: {format_guide} 需要避免:{', '.join(prefs.get('avoid', []))} """ # 如果指定了特定角色,添加角色指令 if role != "default": role_info = self.identity.get("roles", {}).get(role) if role_info: system_message += f"\n\n当前,请你扮演【{role_info.get('name')}】。角色指令:{role_info.get('instruction')}" # 添加上下文知识库(可选,对于长上下文模型可以加入,短上下文模型可摘要或仅在需要时引用) if self.knowledge_base: # 简单截取前2000字符作为上下文,生产环境可根据模型token限制做更智能的摘要或检索 kb_context = self.knowledge_base[:2000] + ("..." if len(self.knowledge_base) > 2000 else "") system_message += f"\n\n以下是用户的知识库上下文,请在回答相关问题时参考:\n---\n{kb_context}\n---" return system_message.strip() def get_prompt_template(self, category: str, template_name: str) -> Optional[Dict]: """获取指定的Prompt模板""" category_templates = self.prompts.get(category, {}).get("templates", {}) # 支持通过名称查找 for key, tmpl in category_templates.items(): if tmpl.get("name") == template_name: return tmpl # 也支持直接通过key查找 return category_templates.get(template_name) if __name__ == "__main__": # 测试加载 loader = ProfileLoader() loader.load_all() print("\n--- 系统提示词示例 ---") print(loader.get_system_prompt(role="code_reviewer")[:500] + "...")4.2 多模型聊天客户端 (scripts/chat_cli.py)
这是一个命令行工具,允许你选择不同的AI模型后端进行对话,并自动注入你的个人档案作为系统指令。
# scripts/chat_cli.py import os import sys from pathlib import Path from dotenv import load_dotenv import argparse from rich.console import Console from rich.markdown import Markdown from rich.panel import Panel from rich.prompt import Prompt, Confirm # 将项目根目录添加到Python路径,以便导入scripts模块 sys.path.insert(0, str(Path(__file__).parent.parent)) from scripts.profile_loader import ProfileLoader # 加载环境变量 load_dotenv() console = Console() class AIClient: """AI客户端基类,定义统一接口""" def __init__(self, model: str, system_prompt: str): self.model = model self.system_prompt = system_prompt self.conversation_history = [{"role": "system", "content": system_prompt}] def chat(self, user_input: str) -> str: """发送消息并获取回复。子类必须实现此方法。""" raise NotImplementedError def reset_conversation(self): """重置对话历史,但保留系统提示词""" self.conversation_history = [{"role": "system", "content": self.system_prompt}] class OpenAIClient(AIClient): def __init__(self, model: str = "gpt-4", system_prompt: str = ""): try: from openai import OpenAI except ImportError: console.print("[red]错误: 未安装openai库。请运行 'pip install openai'[/red]") sys.exit(1) api_key = os.getenv("OPENAI_API_KEY") if not api_key: console.print("[red]错误: 环境变量 OPENAI_API_KEY 未设置。请在 .env 文件中设置。[/red]") sys.exit(1) self.client = OpenAI(api_key=api_key) super().__init__(model, system_prompt) def chat(self, user_input: str) -> str: self.conversation_history.append({"role": "user", "content": user_input}) try: response = self.client.chat.completions.create( model=self.model, messages=self.conversation_history, temperature=0.7, max_tokens=2000 ) ai_reply = response.choices[0].message.content self.conversation_history.append({"role": "assistant", "content": ai_reply}) return ai_reply except Exception as e: return f"[API错误] {e}" class AnthropicClient(AIClient): def __init__(self, model: str = "claude-3-opus-20240229", system_prompt: str = ""): try: import anthropic except ImportError: console.print("[red]错误: 未安装anthropic库。请运行 'pip install anthropic'[/red]") sys.exit(1) api_key = os.getenv("ANTHROPIC_API_KEY") if not api_key: console.print("[red]错误: 环境变量 ANTHROPIC_API_KEY 未设置。请在 .env 文件中设置。[/red]") sys.exit(1) self.client = anthropic.Anthropic(api_key=api_key) # Claude的system提示词是单独参数 self.system_prompt = system_prompt super().__init__(model, system_prompt) # 对话历史格式略有不同 self.conversation_history = [] def chat(self, user_input: str) -> str: self.conversation_history.append({"role": "user", "content": user_input}) try: message = self.client.messages.create( model=self.model, system=self.system_prompt, messages=self.conversation_history, max_tokens=2000, temperature=0.7 ) ai_reply = message.content[0].text self.conversation_history.append({"role": "assistant", "content": ai_reply}) return ai_reply except Exception as e: return f"[API错误] {e}" class GeminiClient(AIClient): def __init__(self, model: str = "gemini-pro", system_prompt: str = ""): try: import google.generativeai as genai except ImportError: console.print("[red]错误: 未安装google-generativeai库。请运行 'pip install google-generativeai'[/red]") sys.exit(1) api_key = os.getenv("GEMINI_API_KEY") if not api_key: console.print("[red]错误: 环境变量 GEMINI_API_KEY 未设置。请在 .env 文件中设置。[/red]") sys.exit(1) genai.configure(api_key=api_key) self.client = genai.GenerativeModel(model_name=model, system_instruction=system_prompt) super().__init__(model, system_prompt) self.chat_session = self.client.start_chat(history=[]) def chat(self, user_input: str) -> str: try: response = self.chat_session.send_message(user_input) ai_reply = response.text return ai_reply except Exception as e: return f"[API错误] {e}" def main(): parser = argparse.ArgumentParser(description="基于个人档案的多模型AI聊天客户端") parser.add_argument("--model", choices=["openai", "claude", "gemini"], default="openai", help="选择AI模型后端 (默认: openai)") parser.add_argument("--role", type=str, default="default", help="指定身份档案中的角色 (例如: 'code_reviewer', 'learning_partner')") args = parser.parse_args() # 1. 加载个人档案 console.print(Panel.fit("🧠 正在加载 AI 个人档案...", style="bold blue")) loader = ProfileLoader() loader.load_all() system_prompt = loader.get_system_prompt(role=args.role) console.print(f"[green]✓ 档案加载成功!当前角色: {args.role}[/green]") # 2. 初始化选定的AI客户端 model_map = { "openai": ("gpt-4", OpenAIClient), "claude": ("claude-3-sonnet-20240229", AnthropicClient), "gemini": ("gemini-pro", GeminiClient), } model_name, client_class = model_map[args.model] console.print(f"[cyan]初始化 {args.model} 客户端 (模型: {model_name})...[/cyan]") ai_client = client_class(model=model_name, system_prompt=system_prompt) # 3. 开始交互式聊天 console.print(Panel.fit("💬 聊天开始!输入 '/quit' 退出, '/reset' 重置对话, '/save' 保存对话。", style="bold green")) while True: try: user_input = Prompt.ask("\n[bold yellow]你[/bold yellow]") if user_input.lower() == '/quit': console.print("[bold red]再见![/bold red]") break elif user_input.lower() == '/reset': ai_client.reset_conversation() console.print("[bold cyan]对话历史已重置。[/bold cyan]") continue elif user_input.lower() == '/save': # 简单的保存功能,可将对话历史保存为Markdown from datetime import datetime timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") filename = f"outputs/chat_{args.model}_{timestamp}.md" Path("outputs").mkdir(exist_ok=True) with open(filename, 'w', encoding='utf-8') as f: f.write(f"# 对话记录 - {args.model} - {timestamp}\n\n") for msg in ai_client.conversation_history if hasattr(ai_client, 'conversation_history') else []: role = msg.get('role', 'unknown') content = msg.get('content', '') f.write(f"## {role}\n\n{content}\n\n") console.print(f"[green]对话已保存至: {filename}[/green]") continue console.print("[bold cyan]AI 正在思考...[/bold cyan]") reply = ai_client.chat(user_input) console.print(Panel(Markdown(reply), title="[bold green]AI[/bold green]", border_style="green")) except KeyboardInterrupt: console.print("\n[yellow]中断操作。[/yellow]") break except Exception as e: console.print(f"[red]发生错误: {e}[/red]") if __name__ == "__main__": main()4.3 输出解析与工具脚本 (scripts/output_parser.py)
AI的回复可能是文本、代码、JSON等。我们可以编写一些工具函数来标准化处理。
# scripts/output_parser.py import re import json from pathlib import Path from typing import Dict, Any, List, Optional def extract_code_blocks(text: str) -> List[Dict[str, str]]: """ 从AI回复中提取Markdown代码块。 返回列表,每个元素是 {'language': lang, 'code': code} """ pattern = r'```(\w+)?\n(.*?)```' matches = re.findall(pattern, text, re.DOTALL) code_blocks = [] for match in matches: lang = match[0] if match[0] else 'text' code = match[1].strip() code_blocks.append({'language': lang, 'code': code}) return code_blocks def save_code_to_file(code_blocks: List[Dict[str, str]], base_dir: str = "./outputs/code"): """ 将提取的代码块保存为单独的文件。 """ Path(base_dir).mkdir(parents=True, exist_ok=True) saved_files = [] for i, block in enumerate(code_blocks): lang = block['language'] code = block['code'] # 简单生成文件名 filename = f"snippet_{i+1}.{lang if lang not in ['python', 'javascript', 'java'] else {'python':'py', 'javascript':'js', 'java':'java'}.get(lang, 'txt')}" filepath = Path(base_dir) / filename with open(filepath, 'w', encoding='utf-8') as f: f.write(code) saved_files.append(str(filepath)) return saved_files def parse_json_from_text(text: str) -> Optional[Dict[str, Any]]: """ 尝试从文本中解析JSON对象。 适用于要求AI返回结构化数据(如任务列表、API响应示例)的场景。 """ # 尝试找到JSON块 json_pattern = r'```json\n(.*?)```' json_match = re.search(json_pattern, text, re.DOTALL) if json_match: json_str = json_match.group(1).strip() else: # 如果没有代码块,尝试直接解析整个文本或找到第一个{...} start_idx = text.find('{') end_idx = text.rfind('}') if start_idx != -1 and end_idx != -1 and end_idx > start_idx: json_str = text[start_idx:end_idx+1] else: return None try: return json.loads(json_str) except json.JSONDecodeError: return None if __name__ == "__main__": # 测试 sample_text = """ 这是一个示例回复。 以下是Python代码: ```python def hello(): print("Hello, World!") ``` 还有一些JSON数据: ```json {"tasks": [{"id": 1, "name": "测试任务"}]} ``` """ print("提取的代码块:", extract_code_blocks(sample_text)) print("解析的JSON:", parse_json_from_text(sample_text))5. 完整工作流演示
现在,让我们从零开始,完整地演示如何使用这套AI个人档案系统。
5.1 第一步:配置环境与档案
- 克隆/创建项目:按照第2.3节创建项目结构。
- 设置API密钥:在项目根目录创建
.env文件,填入你的密钥(切勿上传至公开仓库)。# .env OPENAI_API_KEY=sk-your-openai-key-here ANTHROPIC_API_KEY=sk-ant-your-claude-key-here GEMINI_API_KEY=your-gemini-key-here - 编写你的档案:根据第3节,认真填写
identity.yaml、knowledge_base.md和prompts/下的模板文件。这是整个系统的价值所在。
5.2 第二步:启动聊天客户端
打开终端,进入项目目录,激活虚拟环境,运行客户端。
cd /path/to/ai_personal_profile source venv/bin/activate # Windows: venv\Scripts\activate python scripts/chat_cli.py --model claude --role code_reviewer程序会首先加载你的个人档案,构建包含你身份、偏好和知识库上下文的系统提示词,然后初始化Claude客户端。你将进入一个交互式聊天界面。
5.3 第三步:进行一场“个性化”对话
现在,你可以用你的身份和Claude对话了。例如,直接粘贴一段你的代码:
你:请审查以下Go函数,它用于从数据库分页查询用户列表。 func GetUsers(db *sql.DB, page, size int) ([]User, error) { offset := (page - 1) * size query := `SELECT id, name, email FROM users LIMIT $1 OFFSET $2` rows, err := db.Query(query, size, offset) // ... 后续处理 }由于你在identity.yaml中定义了code_reviewer角色,并在knowledge_base.md中包含了项目技术栈(Go, PostgreSQL),AI的回复将会:
- 以“严格代码审查员”的口吻回应。
- 结合你对“SKIP LOCKED”等技术的了解(来自知识库),给出更贴切的建议。
- 遵循你偏好的“先结论后分点”的回复格式。
5.4 第四步:使用Prompt模板
我们也可以直接使用预定义的Prompt模板。修改或扩展chat_cli.py,增加一个使用模板的功能。这里提供一个简单的示例思路:在聊天循环中,检测特殊命令如/template。
# 在 chat_cli.py 的 main() 函数循环中可添加 if user_input.startswith('/template '): parts = user_input.split(' ', 2) if len(parts) == 3: category, template_name = parts[1], parts[2] template = loader.get_prompt_template(category, template_name) if template: # 这里可以进一步提示用户输入模板变量,然后格式化 console.print(f"[blue]找到模板: {template['name']}[/blue]") console.print(f"[blue]描述: {template['description']}[/blue]") # 示例:简单替换变量(实际应用需要更复杂的变量收集逻辑) # formatted_prompt = template['user_prompt_template'].format(...) # 然后将 formatted_prompt 作为 user_input 发送 else: console.print("[red]未找到指定模板。[/red]") continue5.5 第五步:保存与复用输出
在聊天中使用/save命令,可以将完整的对话历史保存到outputs/目录下的Markdown文件中。你可以定期回顾这些对话,将其中有价值的信息提炼后,反向补充到你的knowledge_base.md中,形成知识积累的闭环。
6. 常见问题与排查思路
在构建和使用个人档案系统时,你可能会遇到以下问题:
| 问题现象 | 可能原因 | 解决思路 |
|---|---|---|
运行python chat_cli.py提示模块导入错误 | 1. 未安装依赖。 2. 未在项目根目录运行。 3. Python路径问题。 | 1. 运行pip install -r requirements.txt。2. 确保在 ai_personal_profile/目录下运行。3. 尝试 python -m scripts.chat_cli。 |
| API调用返回认证错误 | 1..env文件未创建或位置不对。2. API密钥无效或未设置。 3. 环境变量未加载。 | 1. 确保.env文件在项目根目录,且名称正确。2. 检查密钥是否正确,并在对应平台确认是否有效、有余额。 3. 确认代码中 load_dotenv()已调用。 |
| Claude/Gemini客户端初始化失败 | 1. 对应地区的网络限制。 2. Python库版本不兼容。 | 1. 检查网络连接,确认API服务在你所在区域可用(这是平台政策问题,需自行合规解决)。 2. 查看 anthropic或google-generativeai库的官方文档,更新到最新版本。 |
| 系统提示词过长,导致API报错 | 身份档案和知识库内容太多,超过了模型的上下文窗口限制。 | 1. 精简identity.yaml和knowledge_base.md的内容,保留核心。2. 在 profile_loader.py的get_system_prompt方法中,对知识库进行智能摘要或截断。3. 考虑使用向量数据库存储知识库,在对话时进行检索增强生成(RAG),这是进阶方案。 |
| AI的回复不符合身份设定 | 1. 系统提示词构建不清晰。 2. 模型未完全遵循系统指令。 | 1. 检查identity.yaml的格式和内容,确保指令明确无歧义。2. 尝试调整提示词表述,例如使用“你必须”、“请始终”等强调性词语。 3. 不同模型对系统提示词的权重不同,可适当调整。 |
| 想新增一个AI模型支持 | 需要集成新模型的SDK。 | 1. 在chat_cli.py中仿照现有类创建一个新的AIClient子类。2. 安装对应的官方Python SDK。 3. 在 model_map字典中添加映射。 |
7. 最佳实践与进阶建议
7.1 档案维护最佳实践
- 版本化:使用Git管理你的
profile/目录。每次对身份、知识库或Prompt模板做重大更新时,进行一次提交,并写好注释。这能让你随时回滚到某个版本。 - 模块化:不要把所有东西都堆在
knowledge_base.md里。可以按领域拆分,如knowledge_tech.md、knowledge_writing.md,然后在加载时动态组合。 - 定期更新:每完成一个项目或学习一个新概念,花10分钟更新你的知识库。将零散的对话精华,通过你自己的语言总结后归档。
- 保持简洁:系统提示词不是越长越好。聚焦于最核心的身份、最关键的偏好和最高频的知识。过长的提示词会占用宝贵的上下文令牌,并可能降低模型表现。
7.2 工程化与自动化进阶
- 向量化知识库(RAG):当知识库变得庞大时,将其存入ChromaDB、Pinecone等向量数据库。在每次对话前,先检索与用户问题最相关的知识片段,再注入系统提示词。这能突破上下文长度限制,并提升回答的准确性。
- 构建Web界面:使用Gradio、Streamlit或FastAPI + 前端,将你的聊天客户端包装成一个简单的Web应用,方便随时随地使用。
- 集成到开发环境:将你的档案系统与VS Code等IDE结合。例如,开发一个插件,让你在写代码时能一键调用
code_reviewer角色来审查当前代码片段。 - 工作流自动化:结合Zapier、n8n或Python的
schedule库,创建自动化任务。例如,每天早晨让AI根据你的知识库和今日日程,生成一份工作重点简报。
7.3 安全与隐私提醒
- API密钥是最高机密:永远不要将
.env文件或硬编码的密钥提交到公开的Git仓库。使用.gitignore严格过滤。 - 敏感信息脱敏:你的
knowledge_base.md中可能包含内部API地址、服务器信息等。在提交到任何版本控制系统(即使是私有仓库)前,务必进行脱敏处理,或使用环境变量引用。 - 审查AI输出:虽然档案系统能让AI更懂你,但AI生成的内容仍需你最终判断。切勿将未经审核的代码、法律或财务建议直接用于生产环境。
通过以上步骤,你已经成功构建了一套独立于任何单一AI模型的个人智能工作流核心。这套“AI个人档案”的价值会随着你的持续使用和丰富而不断增长。它不再是一个依附于某个网站或应用的临时设置,而是你个人在数字世界的能力延伸和思维外挂。无论明天的AI模型排行榜如何变化,你都可以从容地将你的“档案”接入新的服务,立刻获得一个熟悉你、理解你、能与你高效协作的AI伙伴。