feat: add async LLM tool workflows and richer CLI progress - #6
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors NoteForge’s LLM execution path to support async HTTP, bounded concurrent batch processing, and provider-agnostic tool-calling (with strict local validation + retry), while enhancing CLI progress observability and introducing a shared knowledge taxonomy.
Changes:
- Migrates LLM providers and transport to
asyncusing a reusablehttpx.AsyncClient, and adds a unifiedcall_tool()API across providers. - Adds bounded concurrency (
asyncio.Semaphore) for semantic analysis and knowledge extraction batches, plus richer per-stage activity/progress metrics for the CLI. - Introduces shared taxonomy enums and fixed “submit_*” tools with schemas derived from domain enums.
Reviewed changes
Copilot reviewed 29 out of 31 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| uv.lock | Adds httpx (and dependencies) to the locked dependency set. |
| pyproject.toml | Declares httpx>=0.28,<1 as a runtime dependency. |
| README.md | Adds a development-stage warning and a CLI screenshot. |
| README.zh-CN.md | Adds a development-stage warning and a CLI screenshot (ZH-CN). |
| output/BV18fcozAEsy.md | Adds a large generated sample output markdown file. |
| tests/llm/test_llm.py | Updates tests for async clients/transports and adds tool-call coverage. |
| tests/knowledge/semantic/test_semantic.py | Adds concurrency + retry behavior tests and adapts to async client API. |
| tests/knowledge/prompts/test_prompts.py | Updates prompt expectations (taxonomy wording + constraints). |
| tests/knowledge/extraction/test_extraction.py | Adds normalization and tool-schema derivation tests; adapts async. |
| tests/cli/test_renderer.py | Verifies RUNNING events carry tool/activity details for renderer display. |
| tests/cli/test_app.py | Updates CLI app test to accommodate async client lifecycle/aclose(). |
| src/noteforge/llm/providers/init.py | Replaces urllib transport with async httpx transport and adds aclose(). |
| src/noteforge/llm/providers/openai.py | Makes OpenAI provider async; adds call_tool() + DeepSeek compatibility handling. |
| src/noteforge/llm/providers/ollama.py | Makes Ollama provider async and adds call_tool() parsing. |
| src/noteforge/llm/providers/anthropic.py | Makes Anthropic provider async and adds call_tool() parsing. |
| src/noteforge/llm/models.py | Adds provider-agnostic tool types (LLMTool* models). |
| src/noteforge/llm/base.py | Converts base client API to async and adds default tool fallback + aclose(). |
| src/noteforge/llm/init.py | Re-exports new tool models. |
| src/noteforge/knowledge/taxonomy.py | Introduces shared SemanticChunkType / KnowledgePointType enums. |
| src/noteforge/knowledge/tools.py | Defines fixed tool schemas for semantic analysis and knowledge point submission. |
| src/noteforge/knowledge/semantic/models.py | Switches to shared taxonomy enum import. |
| src/noteforge/knowledge/semantic/analyzer.py | Adds concurrency, activity events, tool-calling, and validation-retry logic. |
| src/noteforge/knowledge/prompts/semantic_analysis.py | Updates prompt to require tool submission rather than raw JSON output. |
| src/noteforge/knowledge/prompts/knowledge_extraction.py | Updates prompt to use taxonomy-driven allowed types and tool submission. |
| src/noteforge/knowledge/extraction/models.py | Switches to shared taxonomy enum import. |
| src/noteforge/knowledge/extraction/validation.py | Adds point_type alias normalization for common upstream semantic labels. |
| src/noteforge/knowledge/extraction/extractor.py | Adds concurrency, activity events, tool-calling, and validation-retry logic. |
| src/noteforge/core/pipeline.py | Tracks monotonic progress, propagates activity metrics, and wires concurrency through pipeline. |
| src/noteforge/cli/renderer.py | Renders richer per-stage RUNNING activity (operation/tool/attempt/model/tokens). |
| src/noteforge/cli/commands/generate.py | Adds --llm-concurrency and ensures client.aclose() after run. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
|
|
||
| class LLMClient(ABC): | ||
| """所有模型供应商必须实现的统一同步接口。""" |
Comment on lines
54
to
+59
| self._progress_handler = progress_handler | ||
| self._activity_handler = activity_handler | ||
| self._max_attempts = max_attempts | ||
| if isinstance(max_concurrency, bool) or not isinstance(max_concurrency, int) or max_concurrency <= 0: | ||
| raise ValueError("max_concurrency 必须是正整数") | ||
| self._max_concurrency = max_concurrency |
Comment on lines
+1
to
+3
| # 固件学习笔记 | ||
|
|
||
| > 本文档整理了 71 个知识点,涵盖基础概念、核心原理、工作流程、示例解析、对比分析、其他知识。 |
Comment on lines
57
to
+62
| self._progress_handler = progress_handler | ||
| self._activity_handler = activity_handler | ||
| self._max_attempts = max_attempts | ||
| if isinstance(max_concurrency, bool) or not isinstance(max_concurrency, int) or max_concurrency <= 0: | ||
| raise ValueError("max_concurrency 必须是正整数") | ||
| self._max_concurrency = max_concurrency |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概述
本 PR 重构了 NoteForge 的 LLM 调用与 CLI 展示链路,在保持确定性 Pipeline 的基础上,引入受约束的工具调用、异步并发请求和更细粒度的运行状态展示,提升笔记生成流程的稳定性、执行效率与可观测性。
主要改动
CLI 展示
--llm-concurrency配置单阶段最大并发批次数LLM 工具调用
submit_semantic_analysis工具submit_knowledge_points工具异步请求与并发
httpx.AsyncClient替换同步 HTTP 请求asyncio.Semaphore控制批次并发asyncio.gather并发处理批次,同时保持最终结果顺序DeepSeek V4 兼容
deepseek-v4-flashtool_choice的 thinking 模式/betaendpoint 不启用 DeepSeek strict beta 参数类型体系与输出稳定性
SemanticChunkType和KnowledgePointType