微信扫码
添加专属顾问
我要投稿
Claude Agent SDK实战:用开源方案打造企业级项目知识库,突破DeepWiki的局限。核心内容: 1. Claude Agent SDK如何赋能AI助手开发 2. 开源版DeepWiki的设计目标与技术实现 3. 代码验证机制确保知识库准确性的关键方案
前一段时间,Anthropic发布了Claude Sonnet 4.5,日常使用中我明显感觉它编码的稳定性相较于4.0有了显著提升。
同时发布的还有全新的Claude Agent SDK。这个SDK其实就是将Claude Code底层强大的Agent能力抽象出来,可以为任何应用场景赋能AI。
Claude Code的强大我在前文《Coding之外:Claude Code如何充当我的工作助手》也有聊到,它内置18个工具,包括本地文件检索、命令执行、任务规划、架构分析等。再结合MCP、自定义指令、子代理、多模态支持等完整的生态系统,让它成为了一个不局限于编程领域的全能AI助手。
说白了,有了Claude Agent SDK,咱们就能复制Claude Code的能力,为自己的业务场景定制专属的AI Agent。
今天的文章就来聊聊我是如何用这个SDK打造一个开源版DeepWiki的。
“claude-deep-wiki项目已开源:https://github.com/skindhu/claude-deep-wiki
我在前文《从Vibe到Spec:让AI编程更可控的结构化思考》中提到过,目前AI辅助编程的最佳实践是Spec Coding —— 通过结构化的需求文档、技术方案、任务拆分来驾驭AI,而不是纯粹的Vibe Coding。
但这里有个关键问题:需求质量。
如果项目需求不够规范,后续无论AI能力多强,生成的代码质量都会大打折扣。这时候,我们就会想到,能否让AI能辅助完善需求?
当然可以,但前提是AI得先理解咱们需求的背景知识:这个功能模块原有的逻辑细节是什么?历史上是如何演进的?有哪些坑?
这就依赖于项目知识库。
我个人觉得目前做得最好的是Devin.ai的DeepWiki。你只需要把Github仓库链接中的github改成deepwiki,就能看到它自动生成的详细项目知识库,效果挺不错。官方还提供了MCP Server支持知识库问答。
但问题来了:
这让我萌生了一个想法:能不能用Claude Agent SDK自己打造一套好用的DeepWiki工具?
有了想法就干。在动手之前,我先明确了几个核心目标和设计原则。
我希望实现的效果是:
如果让单个AI一口气分析完整个代码仓库,基本不可行,先不说上下文是否能容纳这么多内容,最终输出的结果大概率也不可控,可能遗漏重要模块,或编造一些不存在的功能。
更好的方式是:让不同的Agent各司其职,像一个专业团队那样协作。
我设计了三个专职Agent:
这三个Agent按流水线方式工作,每个阶段的输出都是下一个阶段的输入。
有了这个多Agent架构,接下来的问题是:如何让这些Agent拥有稳定地代码分析能力? 刚刚也说了,我们不能一股脑把所有的代码全部塞给它。
Claude Agent SDK比较强大的地方,就是支持创建in-process MCP Server,不需要启动子进程,直接在同一个进程里运行。
这样,我就可以用@tool装饰器快速定义自己的工具集,然后通过create_sdk_mcp_server把它们打包成一个MCP Server,让Agent调用。
我定义了6个核心工具:
from claude_agent_sdk import tool, create_sdk_mcp_server
@tool(
name="scan_repository_structure",
description="扫描代码仓库结构,返回目录树、文件统计和语言分布信息"
)
asyncdef scan_repo_tool(args: Dict[str, Any]) -> Dict[str, Any]:
"""扫描仓库结构"""
result = scan_repository_structure(
repo_path=args["repo_path"],
max_depth=args.get("max_depth", 5)
)
return {"content": [{"type": "text", "text": json.dumps(result)}]}
@tool(name="extract_imports_and_exports", ...)
asyncdef extract_imports_tool(args): ...
@tool(name="analyze_code_block", ...)
asyncdef analyze_code_tool(args): ...
@tool(name="build_dependency_graph", ...)
asyncdef build_dependency_tool(args): ...
@tool(name="search_code_patterns", ...)
asyncdef search_patterns_tool(args): ...
@tool(name="validate_analysis_result", ...)
asyncdef validate_analysis_tool(args): ...
# 创建MCP Server
mcp_server = create_sdk_mcp_server(
name="code-analysis-tools",
tools=[
scan_repo_tool,
extract_imports_tool,
analyze_code_tool,
build_dependency_tool,
search_patterns_tool,
validate_analysis_tool
]
)
这6个工具分别负责:
scan_repository_structure:扫描目录结构,统计文件类型
extract_imports_and_exports:提取文件的导入导出关系(主要基于Tree-sitter AST解析)
analyze_code_block:深度分析代码片段,提取结构化信息(函数、类、导入导出等)
build_dependency_graph:构建模块依赖图,分析循环依赖
search_code_patterns:搜索特定代码模式(API路由、数据库模型等)
validate_analysis_result:验证AI分析结果是否准确(防止编造)
关键点在于:这些工具直接调用Tree-sitter解析AST,提取的都是真实代码结构,AI无法编造。
有了工具集和多Agent架构,接下来就是具体的执行流程了。整个分析过程我分为三个阶段,每个阶段由对应的Agent负责,层层递进。
结构扫描Agent的任务很明确,就是搞清楚这个项目有哪些模块,它们之间的依赖关系是什么。
但这里有个关键设计:分三步走,提升可调试行,同时避免一次性塞爆上下文。
class StructureScannerAgent:
async def scan_repository(self, repo_path: str):
# 步骤1: 扫描结构,识别模块(1次工具调用)
structure = await self._scan_and_identify_modules(repo_path)
# 步骤2: 提取依赖关系(N次工具调用)
dependencies = await self._analyze_file_dependencies(structure, repo_path)
# 步骤3: 整合数据,精确分层(0次工具调用)
final = await self._finalize_structure(structure, dependencies)
步骤1:扫描与识别
只调用1次scan_repository_structure工具,快速扫描目录结构。这一步Claude只看目录名和文件名,就能识别出模块:
src/services/chatService.ts → "聊天服务模块"src/components/Button/ → "按钮组件"src/utils/validator.ts → "验证工具"同时我让Claude为每个模块选出5-10个关键文件,比如入口文件、管理类、核心业务逻辑文件等。
步骤2:依赖分析
针对步骤1选出的关键文件,逐个调用extract_imports_and_exports工具提取导入导出关系。这一步是纯事实提取,AI无法编造:
# chatService.ts的导入导出
{
"imports": ["axios", "./chatUtils", "../config"],
"exports": ["ChatService", "sendMessage"],
"language": "typescript"
}
步骤3:综合分析
拿到了模块列表和依赖关系,最后一步是整合数据。Agent会让Claude分析:
输出是一个完整的项目结构,包括模块清单、依赖图、分层信息。
为什么分三步?
说白了,就是为了准确性。如果让AI一次性扫描全部代码,它可能会遗漏关键信息。分步进行,每步任务明确,结果更可靠,过程中出问题的可调试性也更高。
结构扫描只是识别了“有哪些模块”,但还不知道“这些模块干什么”。语义分析Agent就是来回答这个问题的。
这个阶段有两个关键设计:两轮分析 + 智能分批。
先不急着读每个文件,而是让Claude看模块的整体结构,理解业务价值:
prompt = f"""
你是资深架构师。请分析模块'{module_name}'的业务价值。
关键文件:
- src/services/chatService.ts
- src/utils/chatUtils.ts
请回答:
1. 这个模块的业务目的是什么?
2. 核心功能有哪些?
3. 和其他模块如何交互?
Claude会返回:
{
"business_purpose": "智能客服对话引擎,处理用户问答交互",
"core_features": [
"实时消息收发",
"内容安全过滤",
"多格式消息支持"
],
"external_interactions": [
"调用后端AI服务",
"使用状态管理存储对话"
]
}
有了这个概览,第二轮分析就有了上下文。
第二轮:细节挖掘(批处理)
这里是整个项目最复杂的部分。一个模块可能有几十甚至上百个文件,全部塞给Claude会超过上下文限制。
我的解法是:智能分批 + 按关联度分组。
我设计了FileAnalysisBatchManager ,它会:
字符数 / 3来大致估算,咱们也不需要非常准确class FileAnalysisBatchManager:
def create_file_batches(self, files):
"""按关联度智能分批"""
# 1. 计算文件间的关联度(基于导入关系)
cohesion_scores = self._calculate_cohesion(files)
# 2. 贪心分批:优先将高关联度文件放同一批
batches = []
for file in sorted(files, key=lambda f: cohesion_scores[f], reverse=True):
# 找能容纳这个文件的批次
for batch in batches:
if batch['tokens'] + file['tokens'] < 150000:
batch['files'].append(file)
break
else:
# 创建新批次
batches.append({'files': [file], 'tokens': file['tokens']})
return batches
为什么按关联度分组?
我这里的思考是,Claude分析代码时需要上下文。例如,如果把chatService.ts和chatUtils.ts分到不同批次,Claude就看不到它们的调用关系,分析质量会下降。
每个批次分析完后,Agent会合并结果:
# 批次1结果
{
"files_analysis": [
{"file": "chatService.ts", "functions": [...]},
{"file": "chatUtils.ts", "functions": [...]}
]
}
# 批次2结果
{
"files_analysis": [
{"file": "messageFilter.ts", "functions": [...]}
]
}
# 智能合并
merged = {
"files_analysis": [...], # 所有文件的分析
"cross_file_relationships": [...], # 跨文件关系
"summary": {"total_functions": 4:扫描与识别5, "total_classes": 12}
}
前两个阶段已经把所有技术细节都分析清楚了,但这些内容对于产品经理或业务人员来说还是太技术化。
文档生成Agent主要做三件事:智能分组 → 生成PRD → 生成索引。
步骤1:产品功能域分组
这一步比较有意思,Agent会让Claude扮演资深产品经理,将技术模块重新组织:
prompt = f"""
你是资深产品经理。请将以下技术模块按产品功能域分组:
技术模块:
- components: 通用UI组件
- pages: 各业务页面
- services: API服务调用
- stores: 状态管理
- assets: 静态资源
分组原则:
1. 按业务价值,不是技术架构
2. 每个功能域对应一个独立的产品能力
3. 基础模块可以被多个功能域复用
"""
这里我考虑的关键点是,最终文档的呈现结构应该是基于业务价值,而不是技术架构。
这就是为什么最终文档产品经理能看懂,因为它是用户视角组织的,而不是从代码结构组织的。
步骤2:生成PRD文档
对每个功能域,Agent会生成一份完整的PRD,包含4个标准章节:
“第1章:功能域概述
功能定位(这是干什么的) 业务价值(能带来什么好处) 核心能力列表(提供哪些能力) 子域结构(如果功能域很大,如何进一步划分) 第2章:功能详细说明
每个核心能力的详细描述 使用场景举例 业务流程图(用Mermaid绘制) 业务规则和异常处理 第3章:跨功能交互
对外交互(和其他功能域如何协作)
数据依赖(依赖哪些外部数据或服务)
第4章:业务约束与限制
性能约束、并发限制等
如果功能域包含的文件太多,还会分批生成再智能合并:
async def _generate_prd_multi_batch(self, domain_info, modules_data):
"""大功能域分批生成"""
# 批次1:生成完整框架 + 部分详细内容
batch1 = await self._generate_first_batch(domain_info, modules_data[:10])
# 批次2-N:只生成详细内容
batch2 = await self._generate_continuation(domain_info, modules_data[10:20])
# 智能合并:将批次2的内容插入批次1的"功能详细说明"章节
merged = self._merge_prd_batches([batch1, batch2])
步骤3:质量验证
生成完文档后,Agent会自动检查质量:
def _validate_prd_quality(self, doc):
"""验证PRD质量"""
issues = []
# 检查是否包含技术术语(不应该有)
tech_terms = ['function', 'class', 'API', 'parameter']
for term in tech_terms:
if term in doc:
issues.append(f"包含技术术语: {term}")
# 检查必要章节
required = ['功能详细说明', '业务流程']
for section in required:
if section notin doc:
issues.append(f"缺少章节: {section}")
return issues
如果发现问题,会输出警告,方便我们手动修正。
最终输出的PRD文档,就可以尽量保障是完全面向业务人员的,几乎没有技术术语。
三个阶段的流程看起来很完整,但有个关键问题:如何确保AI的分析是真实可靠的?
这应该是所有DeepWiki类工具都要面对的难题。
为此,我设计了两层防护:
所有的函数名、类名、导入关系都是通过Tree-sitter从AST中提取的,这些是编译器级别的真实数据,AI无法编造。
@tool(name="validate_analysis_result")
asyncdef validate_analysis_tool(args):
"""验证AI分析结果"""
analysis = args["analysis"]
source_code = args["source_code"]
# 1. 用Tree-sitter解析源代码,提取真实结构
actual_functions = extract_functions_from_ast(source_code)
actual_classes = extract_classes_from_ast(source_code)
# 2. 检查AI声称的函数是否都存在
claimed_functions = set(f["name"] for f in analysis["functions"])
fake_functions = claimed_functions - actual_functions
if fake_functions:
return {
"is_valid": False,
"errors": [f"编造的函数: {list(fake_functions)}"]
}
return {"is_valid": True}
在语义分析阶段,Agent会先让Claude分析代码,然后立即调用validate_analysis_result工具验证。如果发现编造,会要求重新分析。
# 分析代码
analysis = await self._analyze_code(file_content)
# 立即验证
validation = await self._validate_analysis(analysis, file_content)
if not validation["is_valid"]:
# 重新分析或标记错误
self._log(f"验证失败: {validation['errors']}")
有了这两层防护,我基本消除了AI编造的风险。实测下来,验证失败率不到5%,而且一旦发现问题立即重新分析,这样就能尽量保障最终输出的准确率。
说完了具体的实现,再聊聊这个过程中我对Claude Agent SDK的一些理解。
Claude Agent SDK的设计哲学,就是对开发者仅暴露出一个结构化的代理循环:收集上下文、执行操作、验证工作和重复。
其它复杂的细节,如工具调用的序列化和反序列化、多轮对话的状态管理、MCP协议的实现细节全部在SDK底层默默做好。而针对不同的工具调用,SDK还提供了多种权限模式,能帮助我们尽量控制代理的安全性。
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业
2025-10-25
Agent从0到1落地实施:以「小智伴」为例,产品需求(一)
2025-10-24
法律人需要有自己的GitHub和Cursor
2025-10-24
MineContext:字节开源的主动式上下文感知 AI 工具,助力高效信息管理
2025-10-24
10 大开源 OCR 模型对比
2025-10-23
从ChatGPT到全模型适配:这个开源项目藏着1000+AI提示词「作弊码」
2025-10-22
DeepSeek 和百度,把 OCR 推到了新水准
2025-10-22
字节开源了一个让人上头的 Context 项目
2025-10-22
Zilliz,源于Milvus,高于Milvus
2025-08-20
2025-09-07
2025-08-05
2025-08-20
2025-07-29
2025-07-31
2025-07-29
2025-08-26
2025-08-22
2025-07-29
2025-10-13
2025-09-29
2025-09-17
2025-09-09
2025-09-08
2025-09-07
2025-09-01
2025-08-16